blob: 540ee9d925bf272459be1bdf1b6f39049cdf9461 [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#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
288#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000289static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000290#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000292
Tim Petersbc2e10e2002-03-03 23:17:02 +0000293#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000294#if defined(PATH_MAX) && PATH_MAX > 1024
295#define MAXPATHLEN PATH_MAX
296#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000297#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000298#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000299#endif /* MAXPATHLEN */
300
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000301#ifdef UNION_WAIT
302/* Emulate some macros on systems that have a union instead of macros */
303
304#ifndef WIFEXITED
305#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
306#endif
307
308#ifndef WEXITSTATUS
309#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
310#endif
311
312#ifndef WTERMSIG
313#define WTERMSIG(u_wait) ((u_wait).w_termsig)
314#endif
315
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000316#define WAIT_TYPE union wait
317#define WAIT_STATUS_INT(s) (s.w_status)
318
319#else /* !UNION_WAIT */
320#define WAIT_TYPE int
321#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000322#endif /* UNION_WAIT */
323
Greg Wardb48bc172000-03-01 21:51:56 +0000324/* Don't use the "_r" form if we don't need it (also, won't have a
325 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200326#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000327#define USE_CTERMID_R
328#endif
329
Fred Drake699f3522000-06-29 21:12:41 +0000330/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000331#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000332#undef FSTAT
333#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200334#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000335# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700336# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200337# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800338# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000339#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000340# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700341# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000342# define FSTAT fstat
343# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000344#endif
345
Tim Peters11b23062003-04-23 02:39:17 +0000346#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000347#include <sys/mkdev.h>
348#else
349#if defined(MAJOR_IN_SYSMACROS)
350#include <sys/sysmacros.h>
351#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000352#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
353#include <sys/mkdev.h>
354#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000355#endif
Fred Drake699f3522000-06-29 21:12:41 +0000356
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200357#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100358#define INITFUNC PyInit_nt
359#define MODNAME "nt"
360#else
361#define INITFUNC PyInit_posix
362#define MODNAME "posix"
363#endif
364
jcea6c51d512018-01-28 14:00:08 +0100365#if defined(__sun)
366/* Something to implement in autoconf, not present in autoconf 2.69 */
367#define HAVE_STRUCT_STAT_ST_FSTYPE 1
368#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200369
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800370#ifdef _Py_MEMORY_SANITIZER
371# include <sanitizer/msan_interface.h>
372#endif
373
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200374#ifdef HAVE_FORK
375static void
376run_at_forkers(PyObject *lst, int reverse)
377{
378 Py_ssize_t i;
379 PyObject *cpy;
380
381 if (lst != NULL) {
382 assert(PyList_CheckExact(lst));
383
384 /* Use a list copy in case register_at_fork() is called from
385 * one of the callbacks.
386 */
387 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
388 if (cpy == NULL)
389 PyErr_WriteUnraisable(lst);
390 else {
391 if (reverse)
392 PyList_Reverse(cpy);
393 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
394 PyObject *func, *res;
395 func = PyList_GET_ITEM(cpy, i);
396 res = PyObject_CallObject(func, NULL);
397 if (res == NULL)
398 PyErr_WriteUnraisable(func);
399 else
400 Py_DECREF(res);
401 }
402 Py_DECREF(cpy);
403 }
404 }
405}
406
407void
408PyOS_BeforeFork(void)
409{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200410 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200411
412 _PyImport_AcquireLock();
413}
414
415void
416PyOS_AfterFork_Parent(void)
417{
418 if (_PyImport_ReleaseLock() <= 0)
419 Py_FatalError("failed releasing import lock after fork");
420
Victor Stinnercaba55b2018-08-03 15:33:52 +0200421 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200422}
423
424void
425PyOS_AfterFork_Child(void)
426{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200427 _PyGILState_Reinit();
Eric Snow59032962018-09-14 14:17:20 -0700428 _PyInterpreterState_DeleteExceptMain();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200429 PyEval_ReInitThreads();
430 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200431 _PySignal_AfterFork();
432
Victor Stinnercaba55b2018-08-03 15:33:52 +0200433 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200434}
435
436static int
437register_at_forker(PyObject **lst, PyObject *func)
438{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700439 if (func == NULL) /* nothing to register? do nothing. */
440 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200441 if (*lst == NULL) {
442 *lst = PyList_New(0);
443 if (*lst == NULL)
444 return -1;
445 }
446 return PyList_Append(*lst, func);
447}
448#endif
449
450/* Legacy wrapper */
451void
452PyOS_AfterFork(void)
453{
454#ifdef HAVE_FORK
455 PyOS_AfterFork_Child();
456#endif
457}
458
459
Victor Stinner6036e442015-03-08 01:58:04 +0100460#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200461/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700462void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
463void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200464 ULONG, struct _Py_stat_struct *);
465#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700466
467#ifdef MS_WINDOWS
468static int
469win32_warn_bytes_api()
470{
471 return PyErr_WarnEx(PyExc_DeprecationWarning,
472 "The Windows bytes API has been deprecated, "
473 "use Unicode filenames instead",
474 1);
475}
476#endif
477
478
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200479#ifndef MS_WINDOWS
480PyObject *
481_PyLong_FromUid(uid_t uid)
482{
483 if (uid == (uid_t)-1)
484 return PyLong_FromLong(-1);
485 return PyLong_FromUnsignedLong(uid);
486}
487
488PyObject *
489_PyLong_FromGid(gid_t gid)
490{
491 if (gid == (gid_t)-1)
492 return PyLong_FromLong(-1);
493 return PyLong_FromUnsignedLong(gid);
494}
495
496int
497_Py_Uid_Converter(PyObject *obj, void *p)
498{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700499 uid_t uid;
500 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200501 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200502 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700503 unsigned long uresult;
504
505 index = PyNumber_Index(obj);
506 if (index == NULL) {
507 PyErr_Format(PyExc_TypeError,
508 "uid should be integer, not %.200s",
509 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200510 return 0;
511 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700512
513 /*
514 * Handling uid_t is complicated for two reasons:
515 * * Although uid_t is (always?) unsigned, it still
516 * accepts -1.
517 * * We don't know its size in advance--it may be
518 * bigger than an int, or it may be smaller than
519 * a long.
520 *
521 * So a bit of defensive programming is in order.
522 * Start with interpreting the value passed
523 * in as a signed long and see if it works.
524 */
525
526 result = PyLong_AsLongAndOverflow(index, &overflow);
527
528 if (!overflow) {
529 uid = (uid_t)result;
530
531 if (result == -1) {
532 if (PyErr_Occurred())
533 goto fail;
534 /* It's a legitimate -1, we're done. */
535 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200536 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537
538 /* Any other negative number is disallowed. */
539 if (result < 0)
540 goto underflow;
541
542 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200543 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700544 (long)uid != result)
545 goto underflow;
546 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200547 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700548
549 if (overflow < 0)
550 goto underflow;
551
552 /*
553 * Okay, the value overflowed a signed long. If it
554 * fits in an *unsigned* long, it may still be okay,
555 * as uid_t may be unsigned long on this platform.
556 */
557 uresult = PyLong_AsUnsignedLong(index);
558 if (PyErr_Occurred()) {
559 if (PyErr_ExceptionMatches(PyExc_OverflowError))
560 goto overflow;
561 goto fail;
562 }
563
564 uid = (uid_t)uresult;
565
566 /*
567 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
568 * but this value would get interpreted as (uid_t)-1 by chown
569 * and its siblings. That's not what the user meant! So we
570 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100571 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700572 */
573 if (uid == (uid_t)-1)
574 goto overflow;
575
576 /* Ensure the value wasn't truncated. */
577 if (sizeof(uid_t) < sizeof(long) &&
578 (unsigned long)uid != uresult)
579 goto overflow;
580 /* fallthrough */
581
582success:
583 Py_DECREF(index);
584 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200585 return 1;
586
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700587underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200588 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700589 "uid is less than minimum");
590 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200593 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700594 "uid is greater than maximum");
595 /* fallthrough */
596
597fail:
598 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200599 return 0;
600}
601
602int
603_Py_Gid_Converter(PyObject *obj, void *p)
604{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700605 gid_t gid;
606 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200607 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200608 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700609 unsigned long uresult;
610
611 index = PyNumber_Index(obj);
612 if (index == NULL) {
613 PyErr_Format(PyExc_TypeError,
614 "gid should be integer, not %.200s",
615 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200616 return 0;
617 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618
619 /*
620 * Handling gid_t is complicated for two reasons:
621 * * Although gid_t is (always?) unsigned, it still
622 * accepts -1.
623 * * We don't know its size in advance--it may be
624 * bigger than an int, or it may be smaller than
625 * a long.
626 *
627 * So a bit of defensive programming is in order.
628 * Start with interpreting the value passed
629 * in as a signed long and see if it works.
630 */
631
632 result = PyLong_AsLongAndOverflow(index, &overflow);
633
634 if (!overflow) {
635 gid = (gid_t)result;
636
637 if (result == -1) {
638 if (PyErr_Occurred())
639 goto fail;
640 /* It's a legitimate -1, we're done. */
641 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200642 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700643
644 /* Any other negative number is disallowed. */
645 if (result < 0) {
646 goto underflow;
647 }
648
649 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200650 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700651 (long)gid != result)
652 goto underflow;
653 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200654 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700655
656 if (overflow < 0)
657 goto underflow;
658
659 /*
660 * Okay, the value overflowed a signed long. If it
661 * fits in an *unsigned* long, it may still be okay,
662 * as gid_t may be unsigned long on this platform.
663 */
664 uresult = PyLong_AsUnsignedLong(index);
665 if (PyErr_Occurred()) {
666 if (PyErr_ExceptionMatches(PyExc_OverflowError))
667 goto overflow;
668 goto fail;
669 }
670
671 gid = (gid_t)uresult;
672
673 /*
674 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
675 * but this value would get interpreted as (gid_t)-1 by chown
676 * and its siblings. That's not what the user meant! So we
677 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100678 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700679 */
680 if (gid == (gid_t)-1)
681 goto overflow;
682
683 /* Ensure the value wasn't truncated. */
684 if (sizeof(gid_t) < sizeof(long) &&
685 (unsigned long)gid != uresult)
686 goto overflow;
687 /* fallthrough */
688
689success:
690 Py_DECREF(index);
691 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200692 return 1;
693
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700694underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200695 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700696 "gid is less than minimum");
697 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200698
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700699overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200700 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700701 "gid is greater than maximum");
702 /* fallthrough */
703
704fail:
705 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200706 return 0;
707}
708#endif /* MS_WINDOWS */
709
710
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700711#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800712
713
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200714#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
715static int
716_Py_Dev_Converter(PyObject *obj, void *p)
717{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200718 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200719 if (PyErr_Occurred())
720 return 0;
721 return 1;
722}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800723#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200724
725
Larry Hastings9cf065c2012-06-22 16:30:09 -0700726#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400727/*
728 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
729 * without the int cast, the value gets interpreted as uint (4291925331),
730 * which doesn't play nicely with all the initializer lines in this file that
731 * look like this:
732 * int dir_fd = DEFAULT_DIR_FD;
733 */
734#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700735#else
736#define DEFAULT_DIR_FD (-100)
737#endif
738
739static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300740_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200741{
742 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700743 long long_value;
744
745 PyObject *index = PyNumber_Index(o);
746 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700747 return 0;
748 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700749
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300750 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700751 long_value = PyLong_AsLongAndOverflow(index, &overflow);
752 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300753 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200754 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700755 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700756 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700757 return 0;
758 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200759 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700761 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700762 return 0;
763 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700764
Larry Hastings9cf065c2012-06-22 16:30:09 -0700765 *p = (int)long_value;
766 return 1;
767}
768
769static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200770dir_fd_converter(PyObject *o, void *p)
771{
772 if (o == Py_None) {
773 *(int *)p = DEFAULT_DIR_FD;
774 return 1;
775 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300776 else if (PyIndex_Check(o)) {
777 return _fd_converter(o, (int *)p);
778 }
779 else {
780 PyErr_Format(PyExc_TypeError,
781 "argument should be integer or None, not %.200s",
782 Py_TYPE(o)->tp_name);
783 return 0;
784 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700785}
786
787
Larry Hastings9cf065c2012-06-22 16:30:09 -0700788/*
789 * A PyArg_ParseTuple "converter" function
790 * that handles filesystem paths in the manner
791 * preferred by the os module.
792 *
793 * path_converter accepts (Unicode) strings and their
794 * subclasses, and bytes and their subclasses. What
795 * it does with the argument depends on the platform:
796 *
797 * * On Windows, if we get a (Unicode) string we
798 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700799 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700800 *
801 * * On all other platforms, strings are encoded
802 * to bytes using PyUnicode_FSConverter, then we
803 * extract the char * from the bytes object and
804 * return that.
805 *
806 * path_converter also optionally accepts signed
807 * integers (representing open file descriptors) instead
808 * of path strings.
809 *
810 * Input fields:
811 * path.nullable
812 * If nonzero, the path is permitted to be None.
813 * path.allow_fd
814 * If nonzero, the path is permitted to be a file handle
815 * (a signed int) instead of a string.
816 * path.function_name
817 * If non-NULL, path_converter will use that as the name
818 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700819 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700820 * path.argument_name
821 * If non-NULL, path_converter will use that as the name
822 * of the parameter in error messages.
823 * (If path.argument_name is NULL it uses "path".)
824 *
825 * Output fields:
826 * path.wide
827 * Points to the path if it was expressed as Unicode
828 * and was not encoded. (Only used on Windows.)
829 * path.narrow
830 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700831 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000832 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700833 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700834 * path.fd
835 * Contains a file descriptor if path.accept_fd was true
836 * and the caller provided a signed integer instead of any
837 * sort of string.
838 *
839 * WARNING: if your "path" parameter is optional, and is
840 * unspecified, path_converter will never get called.
841 * So if you set allow_fd, you *MUST* initialize path.fd = -1
842 * yourself!
843 * path.length
844 * The length of the path in characters, if specified as
845 * a string.
846 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800847 * The original object passed in (if get a PathLike object,
848 * the result of PyOS_FSPath() is treated as the original object).
849 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700850 * path.cleanup
851 * For internal use only. May point to a temporary object.
852 * (Pay no attention to the man behind the curtain.)
853 *
854 * At most one of path.wide or path.narrow will be non-NULL.
855 * If path was None and path.nullable was set,
856 * or if path was an integer and path.allow_fd was set,
857 * both path.wide and path.narrow will be NULL
858 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200859 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700860 * path_converter takes care to not write to the path_t
861 * unless it's successful. However it must reset the
862 * "cleanup" field each time it's called.
863 *
864 * Use as follows:
865 * path_t path;
866 * memset(&path, 0, sizeof(path));
867 * PyArg_ParseTuple(args, "O&", path_converter, &path);
868 * // ... use values from path ...
869 * path_cleanup(&path);
870 *
871 * (Note that if PyArg_Parse fails you don't need to call
872 * path_cleanup(). However it is safe to do so.)
873 */
874typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100875 const char *function_name;
876 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700877 int nullable;
878 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300879 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700880#ifdef MS_WINDOWS
881 BOOL narrow;
882#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300883 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700884#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700885 int fd;
886 Py_ssize_t length;
887 PyObject *object;
888 PyObject *cleanup;
889} path_t;
890
Steve Dowercc16be82016-09-08 10:35:16 -0700891#ifdef MS_WINDOWS
892#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
893 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
894#else
Larry Hastings2f936352014-08-05 14:04:04 +1000895#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
896 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700897#endif
Larry Hastings31826802013-10-19 00:09:25 -0700898
Larry Hastings9cf065c2012-06-22 16:30:09 -0700899static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800900path_cleanup(path_t *path)
901{
902 Py_CLEAR(path->object);
903 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700904}
905
906static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300907path_converter(PyObject *o, void *p)
908{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700909 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800910 PyObject *bytes = NULL;
911 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700912 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300913 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700914#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800915 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700916 const wchar_t *wide;
917#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700918
919#define FORMAT_EXCEPTION(exc, fmt) \
920 PyErr_Format(exc, "%s%s" fmt, \
921 path->function_name ? path->function_name : "", \
922 path->function_name ? ": " : "", \
923 path->argument_name ? path->argument_name : "path")
924
925 /* Py_CLEANUP_SUPPORTED support */
926 if (o == NULL) {
927 path_cleanup(path);
928 return 1;
929 }
930
Brett Cannon3f9183b2016-08-26 14:44:48 -0700931 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800932 path->object = path->cleanup = NULL;
933 /* path->object owns a reference to the original object */
934 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300936 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700938#ifdef MS_WINDOWS
939 path->narrow = FALSE;
940#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700942#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800944 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945 }
946
Brett Cannon3f9183b2016-08-26 14:44:48 -0700947 /* Only call this here so that we don't treat the return value of
948 os.fspath() as an fd or buffer. */
949 is_index = path->allow_fd && PyIndex_Check(o);
950 is_buffer = PyObject_CheckBuffer(o);
951 is_bytes = PyBytes_Check(o);
952 is_unicode = PyUnicode_Check(o);
953
954 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
955 /* Inline PyOS_FSPath() for better error messages. */
956 _Py_IDENTIFIER(__fspath__);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000957 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700958
959 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
960 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800961 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700962 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000963 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700964 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000965 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700966 goto error_exit;
967 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000968 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700969 is_unicode = 1;
970 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000971 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700972 is_bytes = 1;
973 }
974 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000975 PyErr_Format(PyExc_TypeError,
976 "expected %.200s.__fspath__() to return str or bytes, "
977 "not %.200s", Py_TYPE(o)->tp_name,
978 Py_TYPE(res)->tp_name);
979 Py_DECREF(res);
980 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700981 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000982
983 /* still owns a reference to the original object */
984 Py_DECREF(o);
985 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700986 }
987
988 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700989#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +0200990 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100991 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800992 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700993 }
Victor Stinner59799a82013-11-13 14:17:30 +0100994 if (length > 32767) {
995 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +0800996 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700997 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300998 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300999 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001000 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001001 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002
1003 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001004 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001006 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001008 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001009 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001010 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011#endif
1012 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001013 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001014 bytes = o;
1015 Py_INCREF(bytes);
1016 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001017 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001018 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001019 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001020 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1021 "%s%s%s should be %s, not %.200s",
1022 path->function_name ? path->function_name : "",
1023 path->function_name ? ": " : "",
1024 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001025 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1026 "integer or None" :
1027 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1028 path->nullable ? "string, bytes, os.PathLike or None" :
1029 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001030 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001031 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001032 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001033 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001034 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001035 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001036 }
1037 }
Steve Dowercc16be82016-09-08 10:35:16 -07001038 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001039 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001040 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001041 }
1042 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001043#ifdef MS_WINDOWS
1044 path->narrow = FALSE;
1045#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001046 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001047#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001048 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001049 }
1050 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001052 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1053 path->function_name ? path->function_name : "",
1054 path->function_name ? ": " : "",
1055 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001056 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1057 "integer or None" :
1058 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1059 path->nullable ? "string, bytes, os.PathLike or None" :
1060 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001061 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001063 }
1064
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001066 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001067 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001068 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001069 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001070 }
1071
Steve Dowercc16be82016-09-08 10:35:16 -07001072#ifdef MS_WINDOWS
1073 wo = PyUnicode_DecodeFSDefaultAndSize(
1074 narrow,
1075 length
1076 );
1077 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001078 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001079 }
1080
Xiang Zhang04316c42017-01-08 23:26:57 +08001081 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001082 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001083 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001084 }
1085 if (length > 32767) {
1086 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001087 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001088 }
1089 if (wcslen(wide) != length) {
1090 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001091 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001092 }
1093 path->wide = wide;
1094 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001095 path->cleanup = wo;
1096 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001097#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001098 path->wide = NULL;
1099 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001100 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 /* Still a reference owned by path->object, don't have to
1102 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001103 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001104 }
1105 else {
1106 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001107 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001108#endif
1109 path->fd = -1;
1110
1111 success_exit:
1112 path->length = length;
1113 path->object = o;
1114 return Py_CLEANUP_SUPPORTED;
1115
1116 error_exit:
1117 Py_XDECREF(o);
1118 Py_XDECREF(bytes);
1119#ifdef MS_WINDOWS
1120 Py_XDECREF(wo);
1121#endif
1122 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001123}
1124
1125static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001126argument_unavailable_error(const char *function_name, const char *argument_name)
1127{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001128 PyErr_Format(PyExc_NotImplementedError,
1129 "%s%s%s unavailable on this platform",
1130 (function_name != NULL) ? function_name : "",
1131 (function_name != NULL) ? ": ": "",
1132 argument_name);
1133}
1134
1135static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001136dir_fd_unavailable(PyObject *o, void *p)
1137{
1138 int dir_fd;
1139 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001140 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001141 if (dir_fd != DEFAULT_DIR_FD) {
1142 argument_unavailable_error(NULL, "dir_fd");
1143 return 0;
1144 }
1145 *(int *)p = dir_fd;
1146 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001147}
1148
1149static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001150fd_specified(const char *function_name, int fd)
1151{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001152 if (fd == -1)
1153 return 0;
1154
1155 argument_unavailable_error(function_name, "fd");
1156 return 1;
1157}
1158
1159static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001160follow_symlinks_specified(const char *function_name, int follow_symlinks)
1161{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001162 if (follow_symlinks)
1163 return 0;
1164
1165 argument_unavailable_error(function_name, "follow_symlinks");
1166 return 1;
1167}
1168
1169static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001170path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1171{
Steve Dowercc16be82016-09-08 10:35:16 -07001172 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1173#ifndef MS_WINDOWS
1174 && !path->narrow
1175#endif
1176 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 PyErr_Format(PyExc_ValueError,
1178 "%s: can't specify dir_fd without matching path",
1179 function_name);
1180 return 1;
1181 }
1182 return 0;
1183}
1184
1185static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001186dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1187{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001188 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1189 PyErr_Format(PyExc_ValueError,
1190 "%s: can't specify both dir_fd and fd",
1191 function_name);
1192 return 1;
1193 }
1194 return 0;
1195}
1196
1197static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001198fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1199 int follow_symlinks)
1200{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001201 if ((fd > 0) && (!follow_symlinks)) {
1202 PyErr_Format(PyExc_ValueError,
1203 "%s: cannot use fd and follow_symlinks together",
1204 function_name);
1205 return 1;
1206 }
1207 return 0;
1208}
1209
1210static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001211dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1212 int follow_symlinks)
1213{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001214 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1215 PyErr_Format(PyExc_ValueError,
1216 "%s: cannot use dir_fd and follow_symlinks together",
1217 function_name);
1218 return 1;
1219 }
1220 return 0;
1221}
1222
Larry Hastings2f936352014-08-05 14:04:04 +10001223#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001224 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001225#else
Larry Hastings2f936352014-08-05 14:04:04 +10001226 typedef off_t Py_off_t;
1227#endif
1228
1229static int
1230Py_off_t_converter(PyObject *arg, void *addr)
1231{
1232#ifdef HAVE_LARGEFILE_SUPPORT
1233 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1234#else
1235 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001236#endif
1237 if (PyErr_Occurred())
1238 return 0;
1239 return 1;
1240}
Larry Hastings2f936352014-08-05 14:04:04 +10001241
1242static PyObject *
1243PyLong_FromPy_off_t(Py_off_t offset)
1244{
1245#ifdef HAVE_LARGEFILE_SUPPORT
1246 return PyLong_FromLongLong(offset);
1247#else
1248 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001249#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001250}
1251
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001252#ifdef HAVE_SIGSET_T
1253/* Convert an iterable of integers to a sigset.
1254 Return 1 on success, return 0 and raise an exception on error. */
1255int
1256_Py_Sigset_Converter(PyObject *obj, void *addr)
1257{
1258 sigset_t *mask = (sigset_t *)addr;
1259 PyObject *iterator, *item;
1260 long signum;
1261 int overflow;
1262
1263 if (sigemptyset(mask)) {
1264 /* Probably only if mask == NULL. */
1265 PyErr_SetFromErrno(PyExc_OSError);
1266 return 0;
1267 }
1268
1269 iterator = PyObject_GetIter(obj);
1270 if (iterator == NULL) {
1271 return 0;
1272 }
1273
1274 while ((item = PyIter_Next(iterator)) != NULL) {
1275 signum = PyLong_AsLongAndOverflow(item, &overflow);
1276 Py_DECREF(item);
1277 if (signum <= 0 || signum >= NSIG) {
1278 if (overflow || signum != -1 || !PyErr_Occurred()) {
1279 PyErr_Format(PyExc_ValueError,
1280 "signal number %ld out of range", signum);
1281 }
1282 goto error;
1283 }
1284 if (sigaddset(mask, (int)signum)) {
1285 if (errno != EINVAL) {
1286 /* Probably impossible */
1287 PyErr_SetFromErrno(PyExc_OSError);
1288 goto error;
1289 }
1290 /* For backwards compatibility, allow idioms such as
1291 * `range(1, NSIG)` but warn about invalid signal numbers
1292 */
1293 const char msg[] =
1294 "invalid signal number %ld, please use valid_signals()";
1295 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1296 goto error;
1297 }
1298 }
1299 }
1300 if (!PyErr_Occurred()) {
1301 Py_DECREF(iterator);
1302 return 1;
1303 }
1304
1305error:
1306 Py_DECREF(iterator);
1307 return 0;
1308}
1309#endif /* HAVE_SIGSET_T */
1310
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001311#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312
1313static int
Brian Curtind25aef52011-06-13 15:16:04 -05001314win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001315{
Martin Panter70214ad2016-08-04 02:38:59 +00001316 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1317 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001318 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001319
1320 if (0 == DeviceIoControl(
1321 reparse_point_handle,
1322 FSCTL_GET_REPARSE_POINT,
1323 NULL, 0, /* in buffer */
1324 target_buffer, sizeof(target_buffer),
1325 &n_bytes_returned,
1326 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001327 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001328
1329 if (reparse_tag)
1330 *reparse_tag = rdb->ReparseTag;
1331
Brian Curtind25aef52011-06-13 15:16:04 -05001332 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001333}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001334
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001335#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001336
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001338#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001339/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001340** environ directly, we must obtain it with _NSGetEnviron(). See also
1341** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001342*/
1343#include <crt_externs.h>
1344static char **environ;
1345#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001347#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348
Barry Warsaw53699e91996-12-10 23:23:01 +00001349static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001350convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001351{
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001353#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001355#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001356 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001357#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001358
Victor Stinner8c62be82010-05-06 00:08:46 +00001359 d = PyDict_New();
1360 if (d == NULL)
1361 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001362#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 if (environ == NULL)
1364 environ = *_NSGetEnviron();
1365#endif
1366#ifdef MS_WINDOWS
1367 /* _wenviron must be initialized in this way if the program is started
1368 through main() instead of wmain(). */
1369 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001370 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001371#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001372 e = environ;
1373#endif
1374 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001376 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 PyObject *k;
1378 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001379#ifdef MS_WINDOWS
1380 const wchar_t *p = wcschr(*e, L'=');
1381#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001382 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001383#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 if (p == NULL)
1385 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001386#ifdef MS_WINDOWS
1387 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1388#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001389 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001390#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001392 Py_DECREF(d);
1393 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001395#ifdef MS_WINDOWS
1396 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1397#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001398 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001399#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001402 Py_DECREF(d);
1403 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001404 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001405 if (PyDict_GetItemWithError(d, k) == NULL) {
1406 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1407 Py_DECREF(v);
1408 Py_DECREF(k);
1409 Py_DECREF(d);
1410 return NULL;
1411 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001412 }
1413 Py_DECREF(k);
1414 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001415 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001417}
1418
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001419/* Set a POSIX-specific error from errno, and return NULL */
1420
Barry Warsawd58d7641998-07-23 16:14:40 +00001421static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001422posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001423{
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001425}
Mark Hammondef8b6542001-05-13 08:04:26 +00001426
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001427#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001428static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001429win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001430{
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 /* XXX We should pass the function name along in the future.
1432 (winreg.c also wants to pass the function name.)
1433 This would however require an additional param to the
1434 Windows error object, which is non-trivial.
1435 */
1436 errno = GetLastError();
1437 if (filename)
1438 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1439 else
1440 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001441}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001442
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001443static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001444win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001445{
1446 /* XXX - see win32_error for comments on 'function' */
1447 errno = GetLastError();
1448 if (filename)
1449 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001450 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001451 errno,
1452 filename);
1453 else
1454 return PyErr_SetFromWindowsErr(errno);
1455}
1456
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001457#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001458
Larry Hastings9cf065c2012-06-22 16:30:09 -07001459static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001460posix_path_object_error(PyObject *path)
1461{
1462 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1463}
1464
1465static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001466path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001467{
1468#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001469 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1470 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001471#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001472 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001473#endif
1474}
1475
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001476static PyObject *
1477path_object_error2(PyObject *path, PyObject *path2)
1478{
1479#ifdef MS_WINDOWS
1480 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1481 PyExc_OSError, 0, path, path2);
1482#else
1483 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1484#endif
1485}
1486
1487static PyObject *
1488path_error(path_t *path)
1489{
1490 return path_object_error(path->object);
1491}
Larry Hastings31826802013-10-19 00:09:25 -07001492
Larry Hastingsb0827312014-02-09 22:05:19 -08001493static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001494posix_path_error(path_t *path)
1495{
1496 return posix_path_object_error(path->object);
1497}
1498
1499static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001500path_error2(path_t *path, path_t *path2)
1501{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001502 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001503}
1504
1505
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001506/* POSIX generic methods */
1507
Larry Hastings2f936352014-08-05 14:04:04 +10001508static int
1509fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001510{
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001512 int *pointer = (int *)p;
1513 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001515 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001516 *pointer = fd;
1517 return 1;
1518}
1519
1520static PyObject *
1521posix_fildes_fd(int fd, int (*func)(int))
1522{
1523 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001524 int async_err = 0;
1525
1526 do {
1527 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001528 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001529 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001530 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001531 Py_END_ALLOW_THREADS
1532 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1533 if (res != 0)
1534 return (!async_err) ? posix_error() : NULL;
1535 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001536}
Guido van Rossum21142a01999-01-08 21:05:37 +00001537
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001538
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001539#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001540/* This is a reimplementation of the C library's chdir function,
1541 but one that produces Win32 errors instead of DOS error codes.
1542 chdir is essentially a wrapper around SetCurrentDirectory; however,
1543 it also needs to set "magic" environment variables indicating
1544 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001545static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001546win32_wchdir(LPCWSTR path)
1547{
Victor Stinnered537822015-12-13 21:40:26 +01001548 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 int result;
1550 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001551
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 if(!SetCurrentDirectoryW(path))
1553 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001554 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 if (!result)
1556 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001557 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001558 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 if (!new_path) {
1560 SetLastError(ERROR_OUTOFMEMORY);
1561 return FALSE;
1562 }
1563 result = GetCurrentDirectoryW(result, new_path);
1564 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001565 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001566 return FALSE;
1567 }
1568 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001569 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1570 wcsncmp(new_path, L"//", 2) == 0);
1571 if (!is_unc_like_path) {
1572 env[1] = new_path[0];
1573 result = SetEnvironmentVariableW(env, new_path);
1574 }
Victor Stinnered537822015-12-13 21:40:26 +01001575 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001576 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001577 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001578}
1579#endif
1580
Martin v. Löwis14694662006-02-03 12:54:16 +00001581#ifdef MS_WINDOWS
1582/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1583 - time stamps are restricted to second resolution
1584 - file modification times suffer from forth-and-back conversions between
1585 UTC and local time
1586 Therefore, we implement our own stat, based on the Win32 API directly.
1587*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001588#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001589#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001590
Victor Stinner6036e442015-03-08 01:58:04 +01001591static void
Steve Dowercc16be82016-09-08 10:35:16 -07001592find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1593 BY_HANDLE_FILE_INFORMATION *info,
1594 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001595{
1596 memset(info, 0, sizeof(*info));
1597 info->dwFileAttributes = pFileData->dwFileAttributes;
1598 info->ftCreationTime = pFileData->ftCreationTime;
1599 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1600 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1601 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1602 info->nFileSizeLow = pFileData->nFileSizeLow;
1603/* info->nNumberOfLinks = 1; */
1604 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1605 *reparse_tag = pFileData->dwReserved0;
1606 else
1607 *reparse_tag = 0;
1608}
1609
Guido van Rossumd8faa362007-04-27 19:54:29 +00001610static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001611attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001612{
Victor Stinner8c62be82010-05-06 00:08:46 +00001613 HANDLE hFindFile;
1614 WIN32_FIND_DATAW FileData;
1615 hFindFile = FindFirstFileW(pszFile, &FileData);
1616 if (hFindFile == INVALID_HANDLE_VALUE)
1617 return FALSE;
1618 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001619 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001620 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001621}
1622
Brian Curtind25aef52011-06-13 15:16:04 -05001623static BOOL
1624get_target_path(HANDLE hdl, wchar_t **target_path)
1625{
1626 int buf_size, result_length;
1627 wchar_t *buf;
1628
1629 /* We have a good handle to the target, use it to determine
1630 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001631 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1632 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001633 if(!buf_size)
1634 return FALSE;
1635
Victor Stinnerc36674a2016-03-16 14:30:16 +01001636 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001637 if (!buf) {
1638 SetLastError(ERROR_OUTOFMEMORY);
1639 return FALSE;
1640 }
1641
Steve Dower2ea51c92015-03-20 21:49:12 -07001642 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001643 buf, buf_size, VOLUME_NAME_DOS);
1644
1645 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001646 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001647 return FALSE;
1648 }
1649
Brian Curtind25aef52011-06-13 15:16:04 -05001650 buf[result_length] = 0;
1651
1652 *target_path = buf;
1653 return TRUE;
1654}
1655
1656static int
Steve Dowercc16be82016-09-08 10:35:16 -07001657win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001658 BOOL traverse)
1659{
Victor Stinner26de69d2011-06-17 15:15:38 +02001660 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001661 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001663 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001664 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001665 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001666
Steve Dowercc16be82016-09-08 10:35:16 -07001667 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001668 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001669 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670 0, /* share mode */
1671 NULL, /* security attributes */
1672 OPEN_EXISTING,
1673 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001674 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1675 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001676 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001677 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1678 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 NULL);
1680
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001681 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 /* Either the target doesn't exist, or we don't have access to
1683 get a handle to it. If the former, we need to return an error.
1684 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001685 DWORD lastError = GetLastError();
1686 if (lastError != ERROR_ACCESS_DENIED &&
1687 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 return -1;
1689 /* Could not get attributes on open file. Fall back to
1690 reading the directory. */
1691 if (!attributes_from_dir(path, &info, &reparse_tag))
1692 /* Very strange. This should not fail now */
1693 return -1;
1694 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1695 if (traverse) {
1696 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001697 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001698 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001699 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001700 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001701 } else {
1702 if (!GetFileInformationByHandle(hFile, &info)) {
1703 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001704 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001705 }
1706 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Mark Becwarb82bfac2019-02-02 16:08:23 -05001707 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1708 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001709 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001710 }
Brian Curtind25aef52011-06-13 15:16:04 -05001711 /* Close the outer open file handle now that we're about to
1712 reopen it with different flags. */
1713 if (!CloseHandle(hFile))
1714 return -1;
1715
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001716 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001717 /* In order to call GetFinalPathNameByHandle we need to open
1718 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001719 hFile2 = CreateFileW(
1720 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1721 NULL, OPEN_EXISTING,
1722 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1723 NULL);
1724 if (hFile2 == INVALID_HANDLE_VALUE)
1725 return -1;
1726
Mark Becwarb82bfac2019-02-02 16:08:23 -05001727 if (!get_target_path(hFile2, &target_path)) {
1728 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001729 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001730 }
1731
1732 if (!CloseHandle(hFile2)) {
1733 return -1;
1734 }
Brian Curtind25aef52011-06-13 15:16:04 -05001735
Steve Dowercc16be82016-09-08 10:35:16 -07001736 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001737 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001738 return code;
1739 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001740 } else
1741 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001742 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001743 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001744
1745 /* Set S_IEXEC if it is an .exe, .bat, ... */
1746 dot = wcsrchr(path, '.');
1747 if (dot) {
1748 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1749 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1750 result->st_mode |= 0111;
1751 }
1752 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001753}
1754
1755static int
Steve Dowercc16be82016-09-08 10:35:16 -07001756win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001757{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758 /* Protocol violation: we explicitly clear errno, instead of
1759 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001760 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001761 errno = 0;
1762 return code;
1763}
Brian Curtind25aef52011-06-13 15:16:04 -05001764/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001765
1766 In Posix, stat automatically traverses symlinks and returns the stat
1767 structure for the target. In Windows, the equivalent GetFileAttributes by
1768 default does not traverse symlinks and instead returns attributes for
1769 the symlink.
1770
1771 Therefore, win32_lstat will get the attributes traditionally, and
1772 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001773 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001774
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001775static int
Steve Dowercc16be82016-09-08 10:35:16 -07001776win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001777{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001778 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001779}
1780
Victor Stinner8c62be82010-05-06 00:08:46 +00001781static int
Steve Dowercc16be82016-09-08 10:35:16 -07001782win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001783{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001784 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001785}
1786
Martin v. Löwis14694662006-02-03 12:54:16 +00001787#endif /* MS_WINDOWS */
1788
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001789PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001790"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001791This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001792 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001793or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1794\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001795Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1796or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001798See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001799
1800static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001801 {"st_mode", "protection bits"},
1802 {"st_ino", "inode"},
1803 {"st_dev", "device"},
1804 {"st_nlink", "number of hard links"},
1805 {"st_uid", "user ID of owner"},
1806 {"st_gid", "group ID of owner"},
1807 {"st_size", "total size, in bytes"},
1808 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1809 {NULL, "integer time of last access"},
1810 {NULL, "integer time of last modification"},
1811 {NULL, "integer time of last change"},
1812 {"st_atime", "time of last access"},
1813 {"st_mtime", "time of last modification"},
1814 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001815 {"st_atime_ns", "time of last access in nanoseconds"},
1816 {"st_mtime_ns", "time of last modification in nanoseconds"},
1817 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001818#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001820#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001821#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001822 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001823#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001824#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001825 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001826#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001827#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001829#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001830#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001832#endif
1833#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001835#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001836#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1837 {"st_file_attributes", "Windows file attribute bits"},
1838#endif
jcea6c51d512018-01-28 14:00:08 +01001839#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1840 {"st_fstype", "Type of filesystem"},
1841#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001843};
1844
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001845#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001846#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001847#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001848#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849#endif
1850
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001851#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001852#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1853#else
1854#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1855#endif
1856
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001857#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001858#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1859#else
1860#define ST_RDEV_IDX ST_BLOCKS_IDX
1861#endif
1862
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001863#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1864#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1865#else
1866#define ST_FLAGS_IDX ST_RDEV_IDX
1867#endif
1868
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001869#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001870#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001871#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001872#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001873#endif
1874
1875#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1876#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1877#else
1878#define ST_BIRTHTIME_IDX ST_GEN_IDX
1879#endif
1880
Zachary Ware63f277b2014-06-19 09:46:37 -05001881#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1882#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1883#else
1884#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1885#endif
1886
jcea6c51d512018-01-28 14:00:08 +01001887#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1888#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1889#else
1890#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1891#endif
1892
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001893static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001894 "stat_result", /* name */
1895 stat_result__doc__, /* doc */
1896 stat_result_fields,
1897 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001898};
1899
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001900PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001901"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1902This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001903 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001904or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001905\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001906See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001907
1908static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001909 {"f_bsize", },
1910 {"f_frsize", },
1911 {"f_blocks", },
1912 {"f_bfree", },
1913 {"f_bavail", },
1914 {"f_files", },
1915 {"f_ffree", },
1916 {"f_favail", },
1917 {"f_flag", },
1918 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001919 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921};
1922
1923static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 "statvfs_result", /* name */
1925 statvfs_result__doc__, /* doc */
1926 statvfs_result_fields,
1927 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001928};
1929
Ross Lagerwall7807c352011-03-17 20:20:30 +02001930#if defined(HAVE_WAITID) && !defined(__APPLE__)
1931PyDoc_STRVAR(waitid_result__doc__,
1932"waitid_result: Result from waitid.\n\n\
1933This object may be accessed either as a tuple of\n\
1934 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1935or via the attributes si_pid, si_uid, and so on.\n\
1936\n\
1937See os.waitid for more information.");
1938
1939static PyStructSequence_Field waitid_result_fields[] = {
1940 {"si_pid", },
1941 {"si_uid", },
1942 {"si_signo", },
1943 {"si_status", },
1944 {"si_code", },
1945 {0}
1946};
1947
1948static PyStructSequence_Desc waitid_result_desc = {
1949 "waitid_result", /* name */
1950 waitid_result__doc__, /* doc */
1951 waitid_result_fields,
1952 5
1953};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001954static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02001955#endif
1956
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001957static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001958static PyTypeObject* StatResultType;
1959static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07001960#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001961static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001962#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001963static newfunc structseq_new;
1964
1965static PyObject *
1966statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1967{
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 PyStructSequence *result;
1969 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001970
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 result = (PyStructSequence*)structseq_new(type, args, kwds);
1972 if (!result)
1973 return NULL;
1974 /* If we have been initialized from a tuple,
1975 st_?time might be set to None. Initialize it
1976 from the int slots. */
1977 for (i = 7; i <= 9; i++) {
1978 if (result->ob_item[i+3] == Py_None) {
1979 Py_DECREF(Py_None);
1980 Py_INCREF(result->ob_item[i]);
1981 result->ob_item[i+3] = result->ob_item[i];
1982 }
1983 }
1984 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001985}
1986
1987
Larry Hastings6fe20b32012-04-19 15:07:49 -07001988static PyObject *billion = NULL;
1989
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001990static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001991fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001992{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001993 PyObject *s = _PyLong_FromTime_t(sec);
1994 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1995 PyObject *s_in_ns = NULL;
1996 PyObject *ns_total = NULL;
1997 PyObject *float_s = NULL;
1998
1999 if (!(s && ns_fractional))
2000 goto exit;
2001
2002 s_in_ns = PyNumber_Multiply(s, billion);
2003 if (!s_in_ns)
2004 goto exit;
2005
2006 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2007 if (!ns_total)
2008 goto exit;
2009
Victor Stinner01b5aab2017-10-24 02:02:00 -07002010 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2011 if (!float_s) {
2012 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002013 }
2014
2015 PyStructSequence_SET_ITEM(v, index, s);
2016 PyStructSequence_SET_ITEM(v, index+3, float_s);
2017 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2018 s = NULL;
2019 float_s = NULL;
2020 ns_total = NULL;
2021exit:
2022 Py_XDECREF(s);
2023 Py_XDECREF(ns_fractional);
2024 Py_XDECREF(s_in_ns);
2025 Py_XDECREF(ns_total);
2026 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002027}
2028
Tim Peters5aa91602002-01-30 05:46:57 +00002029/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002030 (used by posix_stat() and posix_fstat()) */
2031static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002032_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002033{
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002035 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 if (v == NULL)
2037 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002038
Victor Stinner8c62be82010-05-06 00:08:46 +00002039 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002040 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002041 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002042#ifdef MS_WINDOWS
2043 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002044#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002045 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002046#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002048#if defined(MS_WINDOWS)
2049 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2050 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2051#else
2052 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2053 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2054#endif
xdegaye50e86032017-05-22 11:15:08 +02002055 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2056 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002057
Martin v. Löwis14694662006-02-03 12:54:16 +00002058#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002059 ansec = st->st_atim.tv_nsec;
2060 mnsec = st->st_mtim.tv_nsec;
2061 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002062#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 ansec = st->st_atimespec.tv_nsec;
2064 mnsec = st->st_mtimespec.tv_nsec;
2065 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002066#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 ansec = st->st_atime_nsec;
2068 mnsec = st->st_mtime_nsec;
2069 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002070#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002071 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002072#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002073 fill_time(v, 7, st->st_atime, ansec);
2074 fill_time(v, 8, st->st_mtime, mnsec);
2075 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002076
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002077#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002078 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2079 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002080#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002081#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2083 PyLong_FromLong((long)st->st_blocks));
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_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2087 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002088#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002089#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2091 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002092#endif
2093#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002094 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002095 PyObject *val;
2096 unsigned long bsec,bnsec;
2097 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002098#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002099 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002100#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002101 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002102#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002103 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002104 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2105 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002106 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002107#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002108#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002109 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2110 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002111#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002112#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2113 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2114 PyLong_FromUnsignedLong(st->st_file_attributes));
2115#endif
jcea6c51d512018-01-28 14:00:08 +01002116#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2117 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2118 PyUnicode_FromString(st->st_fstype));
2119#endif
Fred Drake699f3522000-06-29 21:12:41 +00002120
Victor Stinner8c62be82010-05-06 00:08:46 +00002121 if (PyErr_Occurred()) {
2122 Py_DECREF(v);
2123 return NULL;
2124 }
Fred Drake699f3522000-06-29 21:12:41 +00002125
Victor Stinner8c62be82010-05-06 00:08:46 +00002126 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002127}
2128
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002129/* POSIX methods */
2130
Guido van Rossum94f6f721999-01-06 18:42:14 +00002131
2132static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002133posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002134 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002135{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002136 STRUCT_STAT st;
2137 int result;
2138
2139#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2140 if (follow_symlinks_specified(function_name, follow_symlinks))
2141 return NULL;
2142#endif
2143
2144 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2145 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2146 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2147 return NULL;
2148
2149 Py_BEGIN_ALLOW_THREADS
2150 if (path->fd != -1)
2151 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002152#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002153 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002154 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002155 else
Steve Dowercc16be82016-09-08 10:35:16 -07002156 result = win32_lstat(path->wide, &st);
2157#else
2158 else
2159#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002160 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2161 result = LSTAT(path->narrow, &st);
2162 else
Steve Dowercc16be82016-09-08 10:35:16 -07002163#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002164#ifdef HAVE_FSTATAT
2165 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2166 result = fstatat(dir_fd, path->narrow, &st,
2167 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2168 else
Steve Dowercc16be82016-09-08 10:35:16 -07002169#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002170 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002171#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002172 Py_END_ALLOW_THREADS
2173
Victor Stinner292c8352012-10-30 02:17:38 +01002174 if (result != 0) {
2175 return path_error(path);
2176 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002177
2178 return _pystat_fromstructstat(&st);
2179}
2180
Larry Hastings2f936352014-08-05 14:04:04 +10002181/*[python input]
2182
2183for s in """
2184
2185FACCESSAT
2186FCHMODAT
2187FCHOWNAT
2188FSTATAT
2189LINKAT
2190MKDIRAT
2191MKFIFOAT
2192MKNODAT
2193OPENAT
2194READLINKAT
2195SYMLINKAT
2196UNLINKAT
2197
2198""".strip().split():
2199 s = s.strip()
2200 print("""
2201#ifdef HAVE_{s}
2202 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002203#else
Larry Hastings2f936352014-08-05 14:04:04 +10002204 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002205#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002206""".rstrip().format(s=s))
2207
2208for s in """
2209
2210FCHDIR
2211FCHMOD
2212FCHOWN
2213FDOPENDIR
2214FEXECVE
2215FPATHCONF
2216FSTATVFS
2217FTRUNCATE
2218
2219""".strip().split():
2220 s = s.strip()
2221 print("""
2222#ifdef HAVE_{s}
2223 #define PATH_HAVE_{s} 1
2224#else
2225 #define PATH_HAVE_{s} 0
2226#endif
2227
2228""".rstrip().format(s=s))
2229[python start generated code]*/
2230
2231#ifdef HAVE_FACCESSAT
2232 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2233#else
2234 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2235#endif
2236
2237#ifdef HAVE_FCHMODAT
2238 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2239#else
2240 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2241#endif
2242
2243#ifdef HAVE_FCHOWNAT
2244 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2245#else
2246 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2247#endif
2248
2249#ifdef HAVE_FSTATAT
2250 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2251#else
2252 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2253#endif
2254
2255#ifdef HAVE_LINKAT
2256 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2257#else
2258 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2259#endif
2260
2261#ifdef HAVE_MKDIRAT
2262 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2263#else
2264 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2265#endif
2266
2267#ifdef HAVE_MKFIFOAT
2268 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2269#else
2270 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2271#endif
2272
2273#ifdef HAVE_MKNODAT
2274 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2275#else
2276 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2277#endif
2278
2279#ifdef HAVE_OPENAT
2280 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2281#else
2282 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2283#endif
2284
2285#ifdef HAVE_READLINKAT
2286 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2287#else
2288 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2289#endif
2290
2291#ifdef HAVE_SYMLINKAT
2292 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2293#else
2294 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2295#endif
2296
2297#ifdef HAVE_UNLINKAT
2298 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2299#else
2300 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2301#endif
2302
2303#ifdef HAVE_FCHDIR
2304 #define PATH_HAVE_FCHDIR 1
2305#else
2306 #define PATH_HAVE_FCHDIR 0
2307#endif
2308
2309#ifdef HAVE_FCHMOD
2310 #define PATH_HAVE_FCHMOD 1
2311#else
2312 #define PATH_HAVE_FCHMOD 0
2313#endif
2314
2315#ifdef HAVE_FCHOWN
2316 #define PATH_HAVE_FCHOWN 1
2317#else
2318 #define PATH_HAVE_FCHOWN 0
2319#endif
2320
2321#ifdef HAVE_FDOPENDIR
2322 #define PATH_HAVE_FDOPENDIR 1
2323#else
2324 #define PATH_HAVE_FDOPENDIR 0
2325#endif
2326
2327#ifdef HAVE_FEXECVE
2328 #define PATH_HAVE_FEXECVE 1
2329#else
2330 #define PATH_HAVE_FEXECVE 0
2331#endif
2332
2333#ifdef HAVE_FPATHCONF
2334 #define PATH_HAVE_FPATHCONF 1
2335#else
2336 #define PATH_HAVE_FPATHCONF 0
2337#endif
2338
2339#ifdef HAVE_FSTATVFS
2340 #define PATH_HAVE_FSTATVFS 1
2341#else
2342 #define PATH_HAVE_FSTATVFS 0
2343#endif
2344
2345#ifdef HAVE_FTRUNCATE
2346 #define PATH_HAVE_FTRUNCATE 1
2347#else
2348 #define PATH_HAVE_FTRUNCATE 0
2349#endif
2350/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002351
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002352#ifdef MS_WINDOWS
2353 #undef PATH_HAVE_FTRUNCATE
2354 #define PATH_HAVE_FTRUNCATE 1
2355#endif
Larry Hastings31826802013-10-19 00:09:25 -07002356
Larry Hastings61272b72014-01-07 12:41:53 -08002357/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002358
2359class path_t_converter(CConverter):
2360
2361 type = "path_t"
2362 impl_by_reference = True
2363 parse_by_reference = True
2364
2365 converter = 'path_converter'
2366
2367 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002368 # right now path_t doesn't support default values.
2369 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002370 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002371 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002372
Larry Hastings2f936352014-08-05 14:04:04 +10002373 if self.c_default not in (None, 'Py_None'):
2374 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002375
2376 self.nullable = nullable
2377 self.allow_fd = allow_fd
2378
Larry Hastings7726ac92014-01-31 22:03:12 -08002379 def pre_render(self):
2380 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002381 if isinstance(value, str):
2382 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002383 return str(int(bool(value)))
2384
2385 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002386 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002387 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002388 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002389 strify(self.nullable),
2390 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002391 )
2392
2393 def cleanup(self):
2394 return "path_cleanup(&" + self.name + ");\n"
2395
2396
2397class dir_fd_converter(CConverter):
2398 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002399
Larry Hastings2f936352014-08-05 14:04:04 +10002400 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002401 if self.default in (unspecified, None):
2402 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002403 if isinstance(requires, str):
2404 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2405 else:
2406 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002407
Larry Hastings2f936352014-08-05 14:04:04 +10002408class fildes_converter(CConverter):
2409 type = 'int'
2410 converter = 'fildes_converter'
2411
2412class uid_t_converter(CConverter):
2413 type = "uid_t"
2414 converter = '_Py_Uid_Converter'
2415
2416class gid_t_converter(CConverter):
2417 type = "gid_t"
2418 converter = '_Py_Gid_Converter'
2419
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002420class dev_t_converter(CConverter):
2421 type = 'dev_t'
2422 converter = '_Py_Dev_Converter'
2423
2424class dev_t_return_converter(unsigned_long_return_converter):
2425 type = 'dev_t'
2426 conversion_fn = '_PyLong_FromDev'
2427 unsigned_cast = '(dev_t)'
2428
Larry Hastings2f936352014-08-05 14:04:04 +10002429class FSConverter_converter(CConverter):
2430 type = 'PyObject *'
2431 converter = 'PyUnicode_FSConverter'
2432 def converter_init(self):
2433 if self.default is not unspecified:
2434 fail("FSConverter_converter does not support default values")
2435 self.c_default = 'NULL'
2436
2437 def cleanup(self):
2438 return "Py_XDECREF(" + self.name + ");\n"
2439
2440class pid_t_converter(CConverter):
2441 type = 'pid_t'
2442 format_unit = '" _Py_PARSE_PID "'
2443
2444class idtype_t_converter(int_converter):
2445 type = 'idtype_t'
2446
2447class id_t_converter(CConverter):
2448 type = 'id_t'
2449 format_unit = '" _Py_PARSE_PID "'
2450
Benjamin Petersonca470632016-09-06 13:47:26 -07002451class intptr_t_converter(CConverter):
2452 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002453 format_unit = '" _Py_PARSE_INTPTR "'
2454
2455class Py_off_t_converter(CConverter):
2456 type = 'Py_off_t'
2457 converter = 'Py_off_t_converter'
2458
2459class Py_off_t_return_converter(long_return_converter):
2460 type = 'Py_off_t'
2461 conversion_fn = 'PyLong_FromPy_off_t'
2462
2463class path_confname_converter(CConverter):
2464 type="int"
2465 converter="conv_path_confname"
2466
2467class confstr_confname_converter(path_confname_converter):
2468 converter='conv_confstr_confname'
2469
2470class sysconf_confname_converter(path_confname_converter):
2471 converter="conv_sysconf_confname"
2472
2473class sched_param_converter(CConverter):
2474 type = 'struct sched_param'
2475 converter = 'convert_sched_param'
2476 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002477
Larry Hastings61272b72014-01-07 12:41:53 -08002478[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002479/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002480
Larry Hastings61272b72014-01-07 12:41:53 -08002481/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002482
Larry Hastings2a727912014-01-16 11:32:01 -08002483os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002484
2485 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002486 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002487 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002488
2489 *
2490
Larry Hastings2f936352014-08-05 14:04:04 +10002491 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002492 If not None, it should be a file descriptor open to a directory,
2493 and path should be a relative string; path will then be relative to
2494 that directory.
2495
2496 follow_symlinks: bool = True
2497 If False, and the last element of the path is a symbolic link,
2498 stat will examine the symbolic link itself instead of the file
2499 the link points to.
2500
2501Perform a stat system call on the given path.
2502
2503dir_fd and follow_symlinks may not be implemented
2504 on your platform. If they are unavailable, using them will raise a
2505 NotImplementedError.
2506
2507It's an error to use dir_fd or follow_symlinks when specifying path as
2508 an open file descriptor.
2509
Larry Hastings61272b72014-01-07 12:41:53 -08002510[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002511
Larry Hastings31826802013-10-19 00:09:25 -07002512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002513os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002514/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002515{
2516 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2517}
2518
Larry Hastings2f936352014-08-05 14:04:04 +10002519
2520/*[clinic input]
2521os.lstat
2522
2523 path : path_t
2524
2525 *
2526
2527 dir_fd : dir_fd(requires='fstatat') = None
2528
2529Perform a stat system call on the given path, without following symbolic links.
2530
2531Like stat(), but do not follow symbolic links.
2532Equivalent to stat(path, follow_symlinks=False).
2533[clinic start generated code]*/
2534
Larry Hastings2f936352014-08-05 14:04:04 +10002535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002536os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2537/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002538{
2539 int follow_symlinks = 0;
2540 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2541}
Larry Hastings31826802013-10-19 00:09:25 -07002542
Larry Hastings2f936352014-08-05 14:04:04 +10002543
Larry Hastings61272b72014-01-07 12:41:53 -08002544/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002545os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002546
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002547 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002548 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002549
2550 mode: int
2551 Operating-system mode bitfield. Can be F_OK to test existence,
2552 or the inclusive-OR of R_OK, W_OK, and X_OK.
2553
2554 *
2555
Larry Hastings2f936352014-08-05 14:04:04 +10002556 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002557 If not None, it should be a file descriptor open to a directory,
2558 and path should be relative; path will then be relative to that
2559 directory.
2560
2561 effective_ids: bool = False
2562 If True, access will use the effective uid/gid instead of
2563 the real uid/gid.
2564
2565 follow_symlinks: bool = True
2566 If False, and the last element of the path is a symbolic link,
2567 access will examine the symbolic link itself instead of the file
2568 the link points to.
2569
2570Use the real uid/gid to test for access to a path.
2571
2572{parameters}
2573dir_fd, effective_ids, and follow_symlinks may not be implemented
2574 on your platform. If they are unavailable, using them will raise a
2575 NotImplementedError.
2576
2577Note that most operations will use the effective uid/gid, therefore this
2578 routine can be used in a suid/sgid environment to test if the invoking user
2579 has the specified access to the path.
2580
Larry Hastings61272b72014-01-07 12:41:53 -08002581[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002582
Larry Hastings2f936352014-08-05 14:04:04 +10002583static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002584os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002585 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002586/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002587{
Larry Hastings2f936352014-08-05 14:04:04 +10002588 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002589
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002590#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002591 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002592#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002594#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002595
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596#ifndef HAVE_FACCESSAT
2597 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002598 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599
2600 if (effective_ids) {
2601 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002602 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 }
2604#endif
2605
2606#ifdef MS_WINDOWS
2607 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002608 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002609 Py_END_ALLOW_THREADS
2610
2611 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002612 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002613 * * we didn't get a -1, and
2614 * * write access wasn't requested,
2615 * * or the file isn't read-only,
2616 * * or it's a directory.
2617 * (Directories cannot be read-only on Windows.)
2618 */
Larry Hastings2f936352014-08-05 14:04:04 +10002619 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002620 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002622 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623#else
2624
2625 Py_BEGIN_ALLOW_THREADS
2626#ifdef HAVE_FACCESSAT
2627 if ((dir_fd != DEFAULT_DIR_FD) ||
2628 effective_ids ||
2629 !follow_symlinks) {
2630 int flags = 0;
2631 if (!follow_symlinks)
2632 flags |= AT_SYMLINK_NOFOLLOW;
2633 if (effective_ids)
2634 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002635 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002636 }
2637 else
2638#endif
Larry Hastings31826802013-10-19 00:09:25 -07002639 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002640 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002641 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642#endif
2643
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002645}
2646
Guido van Rossumd371ff11999-01-25 16:12:23 +00002647#ifndef F_OK
2648#define F_OK 0
2649#endif
2650#ifndef R_OK
2651#define R_OK 4
2652#endif
2653#ifndef W_OK
2654#define W_OK 2
2655#endif
2656#ifndef X_OK
2657#define X_OK 1
2658#endif
2659
Larry Hastings31826802013-10-19 00:09:25 -07002660
Guido van Rossumd371ff11999-01-25 16:12:23 +00002661#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002662/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002663os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002664
2665 fd: int
2666 Integer file descriptor handle.
2667
2668 /
2669
2670Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002671[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002672
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002674os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002675/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002676{
2677 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002678
Larry Hastings31826802013-10-19 00:09:25 -07002679 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002680 if (ret == NULL) {
2681 return posix_error();
2682 }
2683 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002684}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002685#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002686
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002687#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002688/*[clinic input]
2689os.ctermid
2690
2691Return the name of the controlling terminal for this process.
2692[clinic start generated code]*/
2693
Larry Hastings2f936352014-08-05 14:04:04 +10002694static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002695os_ctermid_impl(PyObject *module)
2696/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002697{
Victor Stinner8c62be82010-05-06 00:08:46 +00002698 char *ret;
2699 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002700
Greg Wardb48bc172000-03-01 21:51:56 +00002701#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002702 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002703#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002704 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002705#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002706 if (ret == NULL)
2707 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002708 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002709}
Larry Hastings2f936352014-08-05 14:04:04 +10002710#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002711
Larry Hastings2f936352014-08-05 14:04:04 +10002712
2713/*[clinic input]
2714os.chdir
2715
2716 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2717
2718Change the current working directory to the specified path.
2719
2720path may always be specified as a string.
2721On some platforms, path may also be specified as an open file descriptor.
2722 If this functionality is unavailable, using it raises an exception.
2723[clinic start generated code]*/
2724
Larry Hastings2f936352014-08-05 14:04:04 +10002725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002726os_chdir_impl(PyObject *module, path_t *path)
2727/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002728{
2729 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002730
2731 Py_BEGIN_ALLOW_THREADS
2732#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002733 /* on unix, success = 0, on windows, success = !0 */
2734 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735#else
2736#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002737 if (path->fd != -1)
2738 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002739 else
2740#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002741 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002742#endif
2743 Py_END_ALLOW_THREADS
2744
2745 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002746 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002747 }
2748
Larry Hastings2f936352014-08-05 14:04:04 +10002749 Py_RETURN_NONE;
2750}
2751
2752
2753#ifdef HAVE_FCHDIR
2754/*[clinic input]
2755os.fchdir
2756
2757 fd: fildes
2758
2759Change to the directory of the given file descriptor.
2760
2761fd must be opened on a directory, not a file.
2762Equivalent to os.chdir(fd).
2763
2764[clinic start generated code]*/
2765
Fred Drake4d1e64b2002-04-15 19:40:07 +00002766static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002767os_fchdir_impl(PyObject *module, int fd)
2768/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002769{
Larry Hastings2f936352014-08-05 14:04:04 +10002770 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002771}
2772#endif /* HAVE_FCHDIR */
2773
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002774
Larry Hastings2f936352014-08-05 14:04:04 +10002775/*[clinic input]
2776os.chmod
2777
2778 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002779 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002780 On some platforms, path may also be specified as an open file descriptor.
2781 If this functionality is unavailable, using it raises an exception.
2782
2783 mode: int
2784 Operating-system mode bitfield.
2785
2786 *
2787
2788 dir_fd : dir_fd(requires='fchmodat') = None
2789 If not None, it should be a file descriptor open to a directory,
2790 and path should be relative; path will then be relative to that
2791 directory.
2792
2793 follow_symlinks: bool = True
2794 If False, and the last element of the path is a symbolic link,
2795 chmod will modify the symbolic link itself instead of the file
2796 the link points to.
2797
2798Change the access permissions of a file.
2799
2800It is an error to use dir_fd or follow_symlinks when specifying path as
2801 an open file descriptor.
2802dir_fd and follow_symlinks may not be implemented on your platform.
2803 If they are unavailable, using them will raise a NotImplementedError.
2804
2805[clinic start generated code]*/
2806
Larry Hastings2f936352014-08-05 14:04:04 +10002807static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002808os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002809 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002810/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002811{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002814#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002815 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002817
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818#ifdef HAVE_FCHMODAT
2819 int fchmodat_nofollow_unsupported = 0;
2820#endif
2821
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2823 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002824 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825#endif
2826
2827#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002829 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002830 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 result = 0;
2832 else {
2833 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002834 attr &= ~FILE_ATTRIBUTE_READONLY;
2835 else
2836 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002837 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002838 }
2839 Py_END_ALLOW_THREADS
2840
2841 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002842 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002843 }
2844#else /* MS_WINDOWS */
2845 Py_BEGIN_ALLOW_THREADS
2846#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002847 if (path->fd != -1)
2848 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002849 else
2850#endif
2851#ifdef HAVE_LCHMOD
2852 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002853 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002854 else
2855#endif
2856#ifdef HAVE_FCHMODAT
2857 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2858 /*
2859 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2860 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002861 * and then says it isn't implemented yet.
2862 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002863 *
2864 * Once it is supported, os.chmod will automatically
2865 * support dir_fd and follow_symlinks=False. (Hopefully.)
2866 * Until then, we need to be careful what exception we raise.
2867 */
Larry Hastings2f936352014-08-05 14:04:04 +10002868 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2870 /*
2871 * But wait! We can't throw the exception without allowing threads,
2872 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2873 */
2874 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002875 result &&
2876 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2877 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002878 }
2879 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002880#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002881 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882 Py_END_ALLOW_THREADS
2883
2884 if (result) {
2885#ifdef HAVE_FCHMODAT
2886 if (fchmodat_nofollow_unsupported) {
2887 if (dir_fd != DEFAULT_DIR_FD)
2888 dir_fd_and_follow_symlinks_invalid("chmod",
2889 dir_fd, follow_symlinks);
2890 else
2891 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002892 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893 }
2894 else
2895#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002896 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897 }
2898#endif
2899
Larry Hastings2f936352014-08-05 14:04:04 +10002900 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002901}
2902
Larry Hastings9cf065c2012-06-22 16:30:09 -07002903
Christian Heimes4e30a842007-11-30 22:12:06 +00002904#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002905/*[clinic input]
2906os.fchmod
2907
2908 fd: int
2909 mode: int
2910
2911Change the access permissions of the file given by file descriptor fd.
2912
2913Equivalent to os.chmod(fd, mode).
2914[clinic start generated code]*/
2915
Larry Hastings2f936352014-08-05 14:04:04 +10002916static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002917os_fchmod_impl(PyObject *module, int fd, int mode)
2918/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002919{
2920 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002921 int async_err = 0;
2922
2923 do {
2924 Py_BEGIN_ALLOW_THREADS
2925 res = fchmod(fd, mode);
2926 Py_END_ALLOW_THREADS
2927 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2928 if (res != 0)
2929 return (!async_err) ? posix_error() : NULL;
2930
Victor Stinner8c62be82010-05-06 00:08:46 +00002931 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002932}
2933#endif /* HAVE_FCHMOD */
2934
Larry Hastings2f936352014-08-05 14:04:04 +10002935
Christian Heimes4e30a842007-11-30 22:12:06 +00002936#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002937/*[clinic input]
2938os.lchmod
2939
2940 path: path_t
2941 mode: int
2942
2943Change the access permissions of a file, without following symbolic links.
2944
2945If path is a symlink, this affects the link itself rather than the target.
2946Equivalent to chmod(path, mode, follow_symlinks=False)."
2947[clinic start generated code]*/
2948
Larry Hastings2f936352014-08-05 14:04:04 +10002949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002950os_lchmod_impl(PyObject *module, path_t *path, int mode)
2951/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002952{
Victor Stinner8c62be82010-05-06 00:08:46 +00002953 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002955 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002956 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002957 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002958 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002959 return NULL;
2960 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002961 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002962}
2963#endif /* HAVE_LCHMOD */
2964
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002965
Thomas Wouterscf297e42007-02-23 15:07:44 +00002966#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002967/*[clinic input]
2968os.chflags
2969
2970 path: path_t
2971 flags: unsigned_long(bitwise=True)
2972 follow_symlinks: bool=True
2973
2974Set file flags.
2975
2976If follow_symlinks is False, and the last element of the path is a symbolic
2977 link, chflags will change flags on the symbolic link itself instead of the
2978 file the link points to.
2979follow_symlinks may not be implemented on your platform. If it is
2980unavailable, using it will raise a NotImplementedError.
2981
2982[clinic start generated code]*/
2983
Larry Hastings2f936352014-08-05 14:04:04 +10002984static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002985os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002986 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002987/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002988{
2989 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002990
2991#ifndef HAVE_LCHFLAGS
2992 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002993 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994#endif
2995
Victor Stinner8c62be82010-05-06 00:08:46 +00002996 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002997#ifdef HAVE_LCHFLAGS
2998 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002999 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003000 else
3001#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003002 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003003 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003004
Larry Hastings2f936352014-08-05 14:04:04 +10003005 if (result)
3006 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007
Larry Hastings2f936352014-08-05 14:04:04 +10003008 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003009}
3010#endif /* HAVE_CHFLAGS */
3011
Larry Hastings2f936352014-08-05 14:04:04 +10003012
Thomas Wouterscf297e42007-02-23 15:07:44 +00003013#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003014/*[clinic input]
3015os.lchflags
3016
3017 path: path_t
3018 flags: unsigned_long(bitwise=True)
3019
3020Set file flags.
3021
3022This function will not follow symbolic links.
3023Equivalent to chflags(path, flags, follow_symlinks=False).
3024[clinic start generated code]*/
3025
Larry Hastings2f936352014-08-05 14:04:04 +10003026static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003027os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3028/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003029{
Victor Stinner8c62be82010-05-06 00:08:46 +00003030 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003031 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003032 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003033 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003034 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003035 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003036 }
Victor Stinner292c8352012-10-30 02:17:38 +01003037 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003038}
3039#endif /* HAVE_LCHFLAGS */
3040
Larry Hastings2f936352014-08-05 14:04:04 +10003041
Martin v. Löwis244edc82001-10-04 22:44:26 +00003042#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003043/*[clinic input]
3044os.chroot
3045 path: path_t
3046
3047Change root directory to path.
3048
3049[clinic start generated code]*/
3050
Larry Hastings2f936352014-08-05 14:04:04 +10003051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003052os_chroot_impl(PyObject *module, path_t *path)
3053/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003054{
3055 int res;
3056 Py_BEGIN_ALLOW_THREADS
3057 res = chroot(path->narrow);
3058 Py_END_ALLOW_THREADS
3059 if (res < 0)
3060 return path_error(path);
3061 Py_RETURN_NONE;
3062}
3063#endif /* HAVE_CHROOT */
3064
Martin v. Löwis244edc82001-10-04 22:44:26 +00003065
Guido van Rossum21142a01999-01-08 21:05:37 +00003066#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003067/*[clinic input]
3068os.fsync
3069
3070 fd: fildes
3071
3072Force write of fd to disk.
3073[clinic start generated code]*/
3074
Larry Hastings2f936352014-08-05 14:04:04 +10003075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003076os_fsync_impl(PyObject *module, int fd)
3077/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003078{
3079 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003080}
3081#endif /* HAVE_FSYNC */
3082
Larry Hastings2f936352014-08-05 14:04:04 +10003083
Ross Lagerwall7807c352011-03-17 20:20:30 +02003084#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003085/*[clinic input]
3086os.sync
3087
3088Force write of everything to disk.
3089[clinic start generated code]*/
3090
Larry Hastings2f936352014-08-05 14:04:04 +10003091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003092os_sync_impl(PyObject *module)
3093/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003094{
3095 Py_BEGIN_ALLOW_THREADS
3096 sync();
3097 Py_END_ALLOW_THREADS
3098 Py_RETURN_NONE;
3099}
Larry Hastings2f936352014-08-05 14:04:04 +10003100#endif /* HAVE_SYNC */
3101
Ross Lagerwall7807c352011-03-17 20:20:30 +02003102
Guido van Rossum21142a01999-01-08 21:05:37 +00003103#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003104#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003105extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3106#endif
3107
Larry Hastings2f936352014-08-05 14:04:04 +10003108/*[clinic input]
3109os.fdatasync
3110
3111 fd: fildes
3112
3113Force write of fd to disk without forcing update of metadata.
3114[clinic start generated code]*/
3115
Larry Hastings2f936352014-08-05 14:04:04 +10003116static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003117os_fdatasync_impl(PyObject *module, int fd)
3118/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003119{
3120 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003121}
3122#endif /* HAVE_FDATASYNC */
3123
3124
Fredrik Lundh10723342000-07-10 16:38:09 +00003125#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003126/*[clinic input]
3127os.chown
3128
3129 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003130 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003131
3132 uid: uid_t
3133
3134 gid: gid_t
3135
3136 *
3137
3138 dir_fd : dir_fd(requires='fchownat') = None
3139 If not None, it should be a file descriptor open to a directory,
3140 and path should be relative; path will then be relative to that
3141 directory.
3142
3143 follow_symlinks: bool = True
3144 If False, and the last element of the path is a symbolic link,
3145 stat will examine the symbolic link itself instead of the file
3146 the link points to.
3147
3148Change the owner and group id of path to the numeric uid and gid.\
3149
3150path may always be specified as a string.
3151On some platforms, path may also be specified as an open file descriptor.
3152 If this functionality is unavailable, using it raises an exception.
3153If dir_fd is not None, it should be a file descriptor open to a directory,
3154 and path should be relative; path will then be relative to that directory.
3155If follow_symlinks is False, and the last element of the path is a symbolic
3156 link, chown will modify the symbolic link itself instead of the file the
3157 link points to.
3158It is an error to use dir_fd or follow_symlinks when specifying path as
3159 an open file descriptor.
3160dir_fd and follow_symlinks may not be implemented on your platform.
3161 If they are unavailable, using them will raise a NotImplementedError.
3162
3163[clinic start generated code]*/
3164
Larry Hastings2f936352014-08-05 14:04:04 +10003165static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003166os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003167 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003168/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003169{
3170 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003171
3172#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3173 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003174 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003176 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3177 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3178 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179
3180#ifdef __APPLE__
3181 /*
3182 * This is for Mac OS X 10.3, which doesn't have lchown.
3183 * (But we still have an lchown symbol because of weak-linking.)
3184 * It doesn't have fchownat either. So there's no possibility
3185 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003186 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187 if ((!follow_symlinks) && (lchown == NULL)) {
3188 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003189 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003190 }
3191#endif
3192
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003195 if (path->fd != -1)
3196 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197 else
3198#endif
3199#ifdef HAVE_LCHOWN
3200 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003201 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202 else
3203#endif
3204#ifdef HAVE_FCHOWNAT
3205 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003206 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3208 else
3209#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003210 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003212
Larry Hastings2f936352014-08-05 14:04:04 +10003213 if (result)
3214 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003215
Larry Hastings2f936352014-08-05 14:04:04 +10003216 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003217}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003218#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003219
Larry Hastings2f936352014-08-05 14:04:04 +10003220
Christian Heimes4e30a842007-11-30 22:12:06 +00003221#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003222/*[clinic input]
3223os.fchown
3224
3225 fd: int
3226 uid: uid_t
3227 gid: gid_t
3228
3229Change the owner and group id of the file specified by file descriptor.
3230
3231Equivalent to os.chown(fd, uid, gid).
3232
3233[clinic start generated code]*/
3234
Larry Hastings2f936352014-08-05 14:04:04 +10003235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003236os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3237/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003238{
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003240 int async_err = 0;
3241
3242 do {
3243 Py_BEGIN_ALLOW_THREADS
3244 res = fchown(fd, uid, gid);
3245 Py_END_ALLOW_THREADS
3246 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3247 if (res != 0)
3248 return (!async_err) ? posix_error() : NULL;
3249
Victor Stinner8c62be82010-05-06 00:08:46 +00003250 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003251}
3252#endif /* HAVE_FCHOWN */
3253
Larry Hastings2f936352014-08-05 14:04:04 +10003254
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003255#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003256/*[clinic input]
3257os.lchown
3258
3259 path : path_t
3260 uid: uid_t
3261 gid: gid_t
3262
3263Change the owner and group id of path to the numeric uid and gid.
3264
3265This function will not follow symbolic links.
3266Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3267[clinic start generated code]*/
3268
Larry Hastings2f936352014-08-05 14:04:04 +10003269static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003270os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3271/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003272{
Victor Stinner8c62be82010-05-06 00:08:46 +00003273 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003274 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003275 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003276 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003277 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003278 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003279 }
Larry Hastings2f936352014-08-05 14:04:04 +10003280 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003281}
3282#endif /* HAVE_LCHOWN */
3283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Barry Warsaw53699e91996-12-10 23:23:01 +00003285static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003286posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003287{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003288 char *buf, *tmpbuf;
3289 char *cwd;
3290 const size_t chunk = 1024;
3291 size_t buflen = 0;
3292 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003293
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003294#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003295 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003296 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003297 wchar_t *wbuf2 = wbuf;
3298 PyObject *resobj;
3299 DWORD len;
3300 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003301 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 /* If the buffer is large enough, len does not include the
3303 terminating \0. If the buffer is too small, len includes
3304 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003305 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003306 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003307 if (wbuf2)
3308 len = GetCurrentDirectoryW(len, wbuf2);
3309 }
3310 Py_END_ALLOW_THREADS
3311 if (!wbuf2) {
3312 PyErr_NoMemory();
3313 return NULL;
3314 }
3315 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003316 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003317 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003318 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003319 }
3320 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003321 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003322 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 return resobj;
3324 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003325
3326 if (win32_warn_bytes_api())
3327 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003328#endif
3329
Victor Stinner4403d7d2015-04-25 00:16:10 +02003330 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003331 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003332 do {
3333 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003334#ifdef MS_WINDOWS
3335 if (buflen > INT_MAX) {
3336 PyErr_NoMemory();
3337 break;
3338 }
3339#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003340 tmpbuf = PyMem_RawRealloc(buf, buflen);
3341 if (tmpbuf == NULL)
3342 break;
3343
3344 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003345#ifdef MS_WINDOWS
3346 cwd = getcwd(buf, (int)buflen);
3347#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003348 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003349#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003350 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003351 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003352
3353 if (cwd == NULL) {
3354 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003355 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003356 }
3357
Victor Stinner8c62be82010-05-06 00:08:46 +00003358 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003359 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3360 else
3361 obj = PyUnicode_DecodeFSDefault(buf);
3362 PyMem_RawFree(buf);
3363
3364 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003365}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003366
Larry Hastings2f936352014-08-05 14:04:04 +10003367
3368/*[clinic input]
3369os.getcwd
3370
3371Return a unicode string representing the current working directory.
3372[clinic start generated code]*/
3373
Larry Hastings2f936352014-08-05 14:04:04 +10003374static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003375os_getcwd_impl(PyObject *module)
3376/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003377{
3378 return posix_getcwd(0);
3379}
3380
Larry Hastings2f936352014-08-05 14:04:04 +10003381
3382/*[clinic input]
3383os.getcwdb
3384
3385Return a bytes string representing the current working directory.
3386[clinic start generated code]*/
3387
Larry Hastings2f936352014-08-05 14:04:04 +10003388static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003389os_getcwdb_impl(PyObject *module)
3390/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003391{
3392 return posix_getcwd(1);
3393}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003394
Larry Hastings2f936352014-08-05 14:04:04 +10003395
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3397#define HAVE_LINK 1
3398#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003399
Guido van Rossumb6775db1994-08-01 11:34:53 +00003400#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003401/*[clinic input]
3402
3403os.link
3404
3405 src : path_t
3406 dst : path_t
3407 *
3408 src_dir_fd : dir_fd = None
3409 dst_dir_fd : dir_fd = None
3410 follow_symlinks: bool = True
3411
3412Create a hard link to a file.
3413
3414If either src_dir_fd or dst_dir_fd is not None, it should be a file
3415 descriptor open to a directory, and the respective path string (src or dst)
3416 should be relative; the path will then be relative to that directory.
3417If follow_symlinks is False, and the last element of src is a symbolic
3418 link, link will create a link to the symbolic link itself instead of the
3419 file the link points to.
3420src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3421 platform. If they are unavailable, using them will raise a
3422 NotImplementedError.
3423[clinic start generated code]*/
3424
Larry Hastings2f936352014-08-05 14:04:04 +10003425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003426os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003427 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003428/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003429{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003431 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432#else
3433 int result;
3434#endif
3435
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436#ifndef HAVE_LINKAT
3437 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3438 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003439 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 }
3441#endif
3442
Steve Dowercc16be82016-09-08 10:35:16 -07003443#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003444 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445 PyErr_SetString(PyExc_NotImplementedError,
3446 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003447 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 }
Steve Dowercc16be82016-09-08 10:35:16 -07003449#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003450
Brian Curtin1b9df392010-11-24 20:24:31 +00003451#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003453 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003455
Larry Hastings2f936352014-08-05 14:04:04 +10003456 if (!result)
3457 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458#else
3459 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003460#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3462 (dst_dir_fd != DEFAULT_DIR_FD) ||
3463 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003464 result = linkat(src_dir_fd, src->narrow,
3465 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3467 else
Steve Dowercc16be82016-09-08 10:35:16 -07003468#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003469 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003471
Larry Hastings2f936352014-08-05 14:04:04 +10003472 if (result)
3473 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003474#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475
Larry Hastings2f936352014-08-05 14:04:04 +10003476 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003477}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478#endif
3479
Brian Curtin1b9df392010-11-24 20:24:31 +00003480
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003481#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003482static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003483_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003484{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 PyObject *v;
3486 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3487 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003488 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003490 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492
Steve Dowercc16be82016-09-08 10:35:16 -07003493 WIN32_FIND_DATAW wFileData;
3494 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003495
Steve Dowercc16be82016-09-08 10:35:16 -07003496 if (!path->wide) { /* Default arg: "." */
3497 po_wchars = L".";
3498 len = 1;
3499 } else {
3500 po_wchars = path->wide;
3501 len = wcslen(path->wide);
3502 }
3503 /* The +5 is so we can append "\\*.*\0" */
3504 wnamebuf = PyMem_New(wchar_t, len + 5);
3505 if (!wnamebuf) {
3506 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 }
Steve Dowercc16be82016-09-08 10:35:16 -07003509 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003511 wchar_t wch = wnamebuf[len-1];
3512 if (wch != SEP && wch != ALTSEP && wch != L':')
3513 wnamebuf[len++] = SEP;
3514 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 }
Steve Dowercc16be82016-09-08 10:35:16 -07003516 if ((list = PyList_New(0)) == NULL) {
3517 goto exit;
3518 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003519 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003520 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003521 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 if (hFindFile == INVALID_HANDLE_VALUE) {
3523 int error = GetLastError();
3524 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 goto exit;
3526 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003527 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 }
3530 do {
3531 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003532 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3533 wcscmp(wFileData.cFileName, L"..") != 0) {
3534 v = PyUnicode_FromWideChar(wFileData.cFileName,
3535 wcslen(wFileData.cFileName));
3536 if (path->narrow && v) {
3537 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3538 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 Py_DECREF(list);
3541 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 break;
3543 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 Py_DECREF(list);
3547 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 break;
3549 }
3550 Py_DECREF(v);
3551 }
3552 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003553 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 Py_END_ALLOW_THREADS
3555 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3556 it got to the end of the directory. */
3557 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003559 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 }
3562 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003563
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564exit:
3565 if (hFindFile != INVALID_HANDLE_VALUE) {
3566 if (FindClose(hFindFile) == FALSE) {
3567 if (list != NULL) {
3568 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003569 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570 }
3571 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003572 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003573 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003574
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003576} /* end of _listdir_windows_no_opendir */
3577
3578#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3579
3580static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003581_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003582{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003583 PyObject *v;
3584 DIR *dirp = NULL;
3585 struct dirent *ep;
3586 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003587#ifdef HAVE_FDOPENDIR
3588 int fd = -1;
3589#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003590
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003593 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003595 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003596 if (fd == -1)
3597 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598
Larry Hastingsfdaea062012-06-25 04:42:23 -07003599 return_str = 1;
3600
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 Py_BEGIN_ALLOW_THREADS
3602 dirp = fdopendir(fd);
3603 Py_END_ALLOW_THREADS
3604 }
3605 else
3606#endif
3607 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003608 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003609 if (path->narrow) {
3610 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003611 /* only return bytes if they specified a bytes-like object */
3612 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003613 }
3614 else {
3615 name = ".";
3616 return_str = 1;
3617 }
3618
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619 Py_BEGIN_ALLOW_THREADS
3620 dirp = opendir(name);
3621 Py_END_ALLOW_THREADS
3622 }
3623
3624 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003625 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003626#ifdef HAVE_FDOPENDIR
3627 if (fd != -1) {
3628 Py_BEGIN_ALLOW_THREADS
3629 close(fd);
3630 Py_END_ALLOW_THREADS
3631 }
3632#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 goto exit;
3634 }
3635 if ((list = PyList_New(0)) == NULL) {
3636 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 }
3638 for (;;) {
3639 errno = 0;
3640 Py_BEGIN_ALLOW_THREADS
3641 ep = readdir(dirp);
3642 Py_END_ALLOW_THREADS
3643 if (ep == NULL) {
3644 if (errno == 0) {
3645 break;
3646 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003648 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003650 }
3651 }
3652 if (ep->d_name[0] == '.' &&
3653 (NAMLEN(ep) == 1 ||
3654 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3655 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003656 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003657 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3658 else
3659 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003661 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 break;
3663 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 break;
3668 }
3669 Py_DECREF(v);
3670 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003671
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672exit:
3673 if (dirp != NULL) {
3674 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003675#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676 if (fd > -1)
3677 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003678#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 closedir(dirp);
3680 Py_END_ALLOW_THREADS
3681 }
3682
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003684} /* end of _posix_listdir */
3685#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003686
Larry Hastings2f936352014-08-05 14:04:04 +10003687
3688/*[clinic input]
3689os.listdir
3690
3691 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3692
3693Return a list containing the names of the files in the directory.
3694
BNMetricsb9427072018-11-02 15:20:19 +00003695path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003696 the filenames returned will also be bytes; in all other circumstances
3697 the filenames returned will be str.
3698If path is None, uses the path='.'.
3699On some platforms, path may also be specified as an open file descriptor;\
3700 the file descriptor must refer to a directory.
3701 If this functionality is unavailable, using it raises NotImplementedError.
3702
3703The list is in arbitrary order. It does not include the special
3704entries '.' and '..' even if they are present in the directory.
3705
3706
3707[clinic start generated code]*/
3708
Larry Hastings2f936352014-08-05 14:04:04 +10003709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003710os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003711/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003712{
3713#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3714 return _listdir_windows_no_opendir(path, NULL);
3715#else
3716 return _posix_listdir(path, NULL);
3717#endif
3718}
3719
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003720#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003721/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003722/*[clinic input]
3723os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003724
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003725 path: path_t
3726 /
3727
3728[clinic start generated code]*/
3729
3730static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003731os__getfullpathname_impl(PyObject *module, path_t *path)
3732/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003733{
Steve Dowercc16be82016-09-08 10:35:16 -07003734 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3735 wchar_t *wtemp;
3736 DWORD result;
3737 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003738
Steve Dowercc16be82016-09-08 10:35:16 -07003739 result = GetFullPathNameW(path->wide,
3740 Py_ARRAY_LENGTH(woutbuf),
3741 woutbuf, &wtemp);
3742 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3743 woutbufp = PyMem_New(wchar_t, result);
3744 if (!woutbufp)
3745 return PyErr_NoMemory();
3746 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003747 }
Steve Dowercc16be82016-09-08 10:35:16 -07003748 if (result) {
3749 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3750 if (path->narrow)
3751 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3752 } else
3753 v = win32_error_object("GetFullPathNameW", path->object);
3754 if (woutbufp != woutbuf)
3755 PyMem_Free(woutbufp);
3756 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003757}
Brian Curtind40e6f72010-07-08 21:39:08 +00003758
Brian Curtind25aef52011-06-13 15:16:04 -05003759
Larry Hastings2f936352014-08-05 14:04:04 +10003760/*[clinic input]
3761os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003762
Steve Dower23ad6d02018-02-22 10:39:10 -08003763 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003764 /
3765
3766A helper function for samepath on windows.
3767[clinic start generated code]*/
3768
Larry Hastings2f936352014-08-05 14:04:04 +10003769static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003770os__getfinalpathname_impl(PyObject *module, path_t *path)
3771/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003772{
3773 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003774 wchar_t buf[MAXPATHLEN], *target_path = buf;
3775 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003776 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003777 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003778
Steve Dower23ad6d02018-02-22 10:39:10 -08003779 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003780 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003781 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003782 0, /* desired access */
3783 0, /* share mode */
3784 NULL, /* security attributes */
3785 OPEN_EXISTING,
3786 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3787 FILE_FLAG_BACKUP_SEMANTICS,
3788 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003789 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003790
Steve Dower23ad6d02018-02-22 10:39:10 -08003791 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003792 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003793 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003794
3795 /* We have a good handle to the target, use it to determine the
3796 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003797 while (1) {
3798 Py_BEGIN_ALLOW_THREADS
3799 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3800 buf_size, VOLUME_NAME_DOS);
3801 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003802
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003803 if (!result_length) {
3804 result = win32_error_object("GetFinalPathNameByHandleW",
3805 path->object);
3806 goto cleanup;
3807 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003808
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003809 if (result_length < buf_size) {
3810 break;
3811 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003812
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003813 wchar_t *tmp;
3814 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3815 result_length * sizeof(*tmp));
3816 if (!tmp) {
3817 result = PyErr_NoMemory();
3818 goto cleanup;
3819 }
3820
3821 buf_size = result_length;
3822 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003823 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003824
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003825 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003826 if (path->narrow)
3827 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003828
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003829cleanup:
3830 if (target_path != buf) {
3831 PyMem_Free(target_path);
3832 }
3833 CloseHandle(hFile);
3834 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003835}
Brian Curtin62857742010-09-06 17:07:27 +00003836
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003837/*[clinic input]
3838os._isdir
3839
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003840 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003841 /
3842
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003843Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003844[clinic start generated code]*/
3845
Brian Curtin9c669cc2011-06-08 18:17:18 -05003846static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003847os__isdir(PyObject *module, PyObject *arg)
3848/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003849{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003850 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003851 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3852
3853 if (!path_converter(arg, &path)) {
3854 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3855 PyErr_Clear();
3856 Py_RETURN_FALSE;
3857 }
3858 return NULL;
3859 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003860
Steve Dowerb22a6772016-07-17 20:49:38 -07003861 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003862 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003863 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003864
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003865 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003866 if (attributes == INVALID_FILE_ATTRIBUTES)
3867 Py_RETURN_FALSE;
3868
Brian Curtin9c669cc2011-06-08 18:17:18 -05003869 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3870 Py_RETURN_TRUE;
3871 else
3872 Py_RETURN_FALSE;
3873}
Tim Golden6b528062013-08-01 12:44:00 +01003874
Tim Golden6b528062013-08-01 12:44:00 +01003875
Larry Hastings2f936352014-08-05 14:04:04 +10003876/*[clinic input]
3877os._getvolumepathname
3878
Steve Dower23ad6d02018-02-22 10:39:10 -08003879 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003880
3881A helper function for ismount on Win32.
3882[clinic start generated code]*/
3883
Larry Hastings2f936352014-08-05 14:04:04 +10003884static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003885os__getvolumepathname_impl(PyObject *module, path_t *path)
3886/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003887{
3888 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003889 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003890 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003891 BOOL ret;
3892
Tim Golden6b528062013-08-01 12:44:00 +01003893 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003894 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003895
Victor Stinner850a18e2017-10-24 16:53:32 -07003896 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003897 PyErr_SetString(PyExc_OverflowError, "path too long");
3898 return NULL;
3899 }
3900
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003901 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003902 if (mountpath == NULL)
3903 return PyErr_NoMemory();
3904
3905 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003906 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003907 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003908 Py_END_ALLOW_THREADS
3909
3910 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003911 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003912 goto exit;
3913 }
3914 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003915 if (path->narrow)
3916 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003917
3918exit:
3919 PyMem_Free(mountpath);
3920 return result;
3921}
Tim Golden6b528062013-08-01 12:44:00 +01003922
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003923#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003924
Larry Hastings2f936352014-08-05 14:04:04 +10003925
3926/*[clinic input]
3927os.mkdir
3928
3929 path : path_t
3930
3931 mode: int = 0o777
3932
3933 *
3934
3935 dir_fd : dir_fd(requires='mkdirat') = None
3936
3937# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3938
3939Create a directory.
3940
3941If dir_fd is not None, it should be a file descriptor open to a directory,
3942 and path should be relative; path will then be relative to that directory.
3943dir_fd may not be implemented on your platform.
3944 If it is unavailable, using it will raise a NotImplementedError.
3945
3946The mode argument is ignored on Windows.
3947[clinic start generated code]*/
3948
Larry Hastings2f936352014-08-05 14:04:04 +10003949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003950os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3951/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003952{
3953 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003954
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003955#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003957 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003958 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003959
Larry Hastings2f936352014-08-05 14:04:04 +10003960 if (!result)
3961 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003962#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003964#if HAVE_MKDIRAT
3965 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003966 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967 else
3968#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003969#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003970 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003971#else
Larry Hastings2f936352014-08-05 14:04:04 +10003972 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003973#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003974 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003975 if (result < 0)
3976 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003977#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003978 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003979}
3980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003981
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003982/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3983#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003984#include <sys/resource.h>
3985#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003986
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003987
3988#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003989/*[clinic input]
3990os.nice
3991
3992 increment: int
3993 /
3994
3995Add increment to the priority of process and return the new priority.
3996[clinic start generated code]*/
3997
Larry Hastings2f936352014-08-05 14:04:04 +10003998static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003999os_nice_impl(PyObject *module, int increment)
4000/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004001{
4002 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004003
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 /* There are two flavours of 'nice': one that returns the new
4005 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004006 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004008
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 If we are of the nice family that returns the new priority, we
4010 need to clear errno before the call, and check if errno is filled
4011 before calling posix_error() on a returnvalue of -1, because the
4012 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004013
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 errno = 0;
4015 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004016#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 if (value == 0)
4018 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004019#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004020 if (value == -1 && errno != 0)
4021 /* either nice() or getpriority() returned an error */
4022 return posix_error();
4023 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004024}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004025#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004026
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004027
4028#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004029/*[clinic input]
4030os.getpriority
4031
4032 which: int
4033 who: int
4034
4035Return program scheduling priority.
4036[clinic start generated code]*/
4037
Larry Hastings2f936352014-08-05 14:04:04 +10004038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004039os_getpriority_impl(PyObject *module, int which, int who)
4040/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004041{
4042 int retval;
4043
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004044 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004045 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004046 if (errno != 0)
4047 return posix_error();
4048 return PyLong_FromLong((long)retval);
4049}
4050#endif /* HAVE_GETPRIORITY */
4051
4052
4053#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004054/*[clinic input]
4055os.setpriority
4056
4057 which: int
4058 who: int
4059 priority: int
4060
4061Set program scheduling priority.
4062[clinic start generated code]*/
4063
Larry Hastings2f936352014-08-05 14:04:04 +10004064static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004065os_setpriority_impl(PyObject *module, int which, int who, int priority)
4066/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004067{
4068 int retval;
4069
4070 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004071 if (retval == -1)
4072 return posix_error();
4073 Py_RETURN_NONE;
4074}
4075#endif /* HAVE_SETPRIORITY */
4076
4077
Barry Warsaw53699e91996-12-10 23:23:01 +00004078static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004079internal_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 +00004080{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004081 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004082 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004084#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004085 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004086 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004087#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004089#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4092 (dst_dir_fd != DEFAULT_DIR_FD);
4093#ifndef HAVE_RENAMEAT
4094 if (dir_fd_specified) {
4095 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004096 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004097 }
4098#endif
4099
Larry Hastings9cf065c2012-06-22 16:30:09 -07004100#ifdef MS_WINDOWS
4101 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004102 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004103 Py_END_ALLOW_THREADS
4104
Larry Hastings2f936352014-08-05 14:04:04 +10004105 if (!result)
4106 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004107
4108#else
Steve Dowercc16be82016-09-08 10:35:16 -07004109 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4110 PyErr_Format(PyExc_ValueError,
4111 "%s: src and dst must be the same type", function_name);
4112 return NULL;
4113 }
4114
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115 Py_BEGIN_ALLOW_THREADS
4116#ifdef HAVE_RENAMEAT
4117 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004118 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119 else
4120#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004121 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 Py_END_ALLOW_THREADS
4123
Larry Hastings2f936352014-08-05 14:04:04 +10004124 if (result)
4125 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004127 Py_RETURN_NONE;
4128}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129
Larry Hastings2f936352014-08-05 14:04:04 +10004130
4131/*[clinic input]
4132os.rename
4133
4134 src : path_t
4135 dst : path_t
4136 *
4137 src_dir_fd : dir_fd = None
4138 dst_dir_fd : dir_fd = None
4139
4140Rename a file or directory.
4141
4142If either src_dir_fd or dst_dir_fd is not None, it should be a file
4143 descriptor open to a directory, and the respective path string (src or dst)
4144 should be relative; the path will then be relative to that directory.
4145src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4146 If they are unavailable, using them will raise a NotImplementedError.
4147[clinic start generated code]*/
4148
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004149static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004150os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004151 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004152/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004153{
Larry Hastings2f936352014-08-05 14:04:04 +10004154 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004155}
4156
Larry Hastings2f936352014-08-05 14:04:04 +10004157
4158/*[clinic input]
4159os.replace = os.rename
4160
4161Rename a file or directory, overwriting the destination.
4162
4163If either src_dir_fd or dst_dir_fd is not None, it should be a file
4164 descriptor open to a directory, and the respective path string (src or dst)
4165 should be relative; the path will then be relative to that directory.
4166src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004167 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004168[clinic start generated code]*/
4169
Larry Hastings2f936352014-08-05 14:04:04 +10004170static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004171os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4172 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004173/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004174{
4175 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4176}
4177
4178
4179/*[clinic input]
4180os.rmdir
4181
4182 path: path_t
4183 *
4184 dir_fd: dir_fd(requires='unlinkat') = None
4185
4186Remove a directory.
4187
4188If dir_fd is not None, it should be a file descriptor open to a directory,
4189 and path should be relative; path will then be relative to that directory.
4190dir_fd may not be implemented on your platform.
4191 If it is unavailable, using it will raise a NotImplementedError.
4192[clinic start generated code]*/
4193
Larry Hastings2f936352014-08-05 14:04:04 +10004194static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004195os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4196/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004197{
4198 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004199
4200 Py_BEGIN_ALLOW_THREADS
4201#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004202 /* Windows, success=1, UNIX, success=0 */
4203 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004204#else
4205#ifdef HAVE_UNLINKAT
4206 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004207 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004208 else
4209#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004210 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004211#endif
4212 Py_END_ALLOW_THREADS
4213
Larry Hastings2f936352014-08-05 14:04:04 +10004214 if (result)
4215 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004216
Larry Hastings2f936352014-08-05 14:04:04 +10004217 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004218}
4219
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004220
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004221#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004222#ifdef MS_WINDOWS
4223/*[clinic input]
4224os.system -> long
4225
4226 command: Py_UNICODE
4227
4228Execute the command in a subshell.
4229[clinic start generated code]*/
4230
Larry Hastings2f936352014-08-05 14:04:04 +10004231static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004232os_system_impl(PyObject *module, const Py_UNICODE *command)
4233/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004234{
4235 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004237 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004239 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004240 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004241 return result;
4242}
4243#else /* MS_WINDOWS */
4244/*[clinic input]
4245os.system -> long
4246
4247 command: FSConverter
4248
4249Execute the command in a subshell.
4250[clinic start generated code]*/
4251
Larry Hastings2f936352014-08-05 14:04:04 +10004252static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004253os_system_impl(PyObject *module, PyObject *command)
4254/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004255{
4256 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004257 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004258 Py_BEGIN_ALLOW_THREADS
4259 result = system(bytes);
4260 Py_END_ALLOW_THREADS
4261 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004262}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004263#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004264#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004266
Larry Hastings2f936352014-08-05 14:04:04 +10004267/*[clinic input]
4268os.umask
4269
4270 mask: int
4271 /
4272
4273Set the current numeric umask and return the previous umask.
4274[clinic start generated code]*/
4275
Larry Hastings2f936352014-08-05 14:04:04 +10004276static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004277os_umask_impl(PyObject *module, int mask)
4278/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004279{
4280 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004281 if (i < 0)
4282 return posix_error();
4283 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004284}
4285
Brian Curtind40e6f72010-07-08 21:39:08 +00004286#ifdef MS_WINDOWS
4287
4288/* override the default DeleteFileW behavior so that directory
4289symlinks can be removed with this function, the same as with
4290Unix symlinks */
4291BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4292{
4293 WIN32_FILE_ATTRIBUTE_DATA info;
4294 WIN32_FIND_DATAW find_data;
4295 HANDLE find_data_handle;
4296 int is_directory = 0;
4297 int is_link = 0;
4298
4299 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4300 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004301
Brian Curtind40e6f72010-07-08 21:39:08 +00004302 /* Get WIN32_FIND_DATA structure for the path to determine if
4303 it is a symlink */
4304 if(is_directory &&
4305 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4306 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4307
4308 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004309 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4310 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4311 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4312 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004313 FindClose(find_data_handle);
4314 }
4315 }
4316 }
4317
4318 if (is_directory && is_link)
4319 return RemoveDirectoryW(lpFileName);
4320
4321 return DeleteFileW(lpFileName);
4322}
4323#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004325
Larry Hastings2f936352014-08-05 14:04:04 +10004326/*[clinic input]
4327os.unlink
4328
4329 path: path_t
4330 *
4331 dir_fd: dir_fd(requires='unlinkat')=None
4332
4333Remove a file (same as remove()).
4334
4335If dir_fd is not None, it should be a file descriptor open to a directory,
4336 and path should be relative; path will then be relative to that directory.
4337dir_fd may not be implemented on your platform.
4338 If it is unavailable, using it will raise a NotImplementedError.
4339
4340[clinic start generated code]*/
4341
Larry Hastings2f936352014-08-05 14:04:04 +10004342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004343os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4344/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004345{
4346 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004347
4348 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004349 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004350#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004351 /* Windows, success=1, UNIX, success=0 */
4352 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004353#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004354#ifdef HAVE_UNLINKAT
4355 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004356 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357 else
4358#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004359 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004361 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004362 Py_END_ALLOW_THREADS
4363
Larry Hastings2f936352014-08-05 14:04:04 +10004364 if (result)
4365 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004366
Larry Hastings2f936352014-08-05 14:04:04 +10004367 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004368}
4369
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004370
Larry Hastings2f936352014-08-05 14:04:04 +10004371/*[clinic input]
4372os.remove = os.unlink
4373
4374Remove a file (same as unlink()).
4375
4376If dir_fd is not None, it should be a file descriptor open to a directory,
4377 and path should be relative; path will then be relative to that directory.
4378dir_fd may not be implemented on your platform.
4379 If it is unavailable, using it will raise a NotImplementedError.
4380[clinic start generated code]*/
4381
Larry Hastings2f936352014-08-05 14:04:04 +10004382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004383os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4384/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004385{
4386 return os_unlink_impl(module, path, dir_fd);
4387}
4388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004389
Larry Hastings605a62d2012-06-24 04:33:36 -07004390static PyStructSequence_Field uname_result_fields[] = {
4391 {"sysname", "operating system name"},
4392 {"nodename", "name of machine on network (implementation-defined)"},
4393 {"release", "operating system release"},
4394 {"version", "operating system version"},
4395 {"machine", "hardware identifier"},
4396 {NULL}
4397};
4398
4399PyDoc_STRVAR(uname_result__doc__,
4400"uname_result: Result from os.uname().\n\n\
4401This object may be accessed either as a tuple of\n\
4402 (sysname, nodename, release, version, machine),\n\
4403or via the attributes sysname, nodename, release, version, and machine.\n\
4404\n\
4405See os.uname for more information.");
4406
4407static PyStructSequence_Desc uname_result_desc = {
4408 "uname_result", /* name */
4409 uname_result__doc__, /* doc */
4410 uname_result_fields,
4411 5
4412};
4413
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004414static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004415
4416
4417#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004418/*[clinic input]
4419os.uname
4420
4421Return an object identifying the current operating system.
4422
4423The object behaves like a named tuple with the following fields:
4424 (sysname, nodename, release, version, machine)
4425
4426[clinic start generated code]*/
4427
Larry Hastings2f936352014-08-05 14:04:04 +10004428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004429os_uname_impl(PyObject *module)
4430/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004431{
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 struct utsname u;
4433 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004434 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004435
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 Py_BEGIN_ALLOW_THREADS
4437 res = uname(&u);
4438 Py_END_ALLOW_THREADS
4439 if (res < 0)
4440 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004441
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004442 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004443 if (value == NULL)
4444 return NULL;
4445
4446#define SET(i, field) \
4447 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004448 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004449 if (!o) { \
4450 Py_DECREF(value); \
4451 return NULL; \
4452 } \
4453 PyStructSequence_SET_ITEM(value, i, o); \
4454 } \
4455
4456 SET(0, u.sysname);
4457 SET(1, u.nodename);
4458 SET(2, u.release);
4459 SET(3, u.version);
4460 SET(4, u.machine);
4461
4462#undef SET
4463
4464 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004465}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004466#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004467
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004468
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469
4470typedef struct {
4471 int now;
4472 time_t atime_s;
4473 long atime_ns;
4474 time_t mtime_s;
4475 long mtime_ns;
4476} utime_t;
4477
4478/*
Victor Stinner484df002014-10-09 13:52:31 +02004479 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480 * they also intentionally leak the declaration of a pointer named "time"
4481 */
4482#define UTIME_TO_TIMESPEC \
4483 struct timespec ts[2]; \
4484 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004485 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486 time = NULL; \
4487 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004488 ts[0].tv_sec = ut->atime_s; \
4489 ts[0].tv_nsec = ut->atime_ns; \
4490 ts[1].tv_sec = ut->mtime_s; \
4491 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492 time = ts; \
4493 } \
4494
4495#define UTIME_TO_TIMEVAL \
4496 struct timeval tv[2]; \
4497 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004498 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499 time = NULL; \
4500 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004501 tv[0].tv_sec = ut->atime_s; \
4502 tv[0].tv_usec = ut->atime_ns / 1000; \
4503 tv[1].tv_sec = ut->mtime_s; \
4504 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004505 time = tv; \
4506 } \
4507
4508#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004509 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004511 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004512 time = NULL; \
4513 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004514 u.actime = ut->atime_s; \
4515 u.modtime = ut->mtime_s; \
4516 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517 }
4518
4519#define UTIME_TO_TIME_T \
4520 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004521 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004522 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004523 time = NULL; \
4524 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004525 timet[0] = ut->atime_s; \
4526 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004527 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004528 } \
4529
4530
Victor Stinner528a9ab2015-09-03 21:30:26 +02004531#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532
4533static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004534utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535{
4536#ifdef HAVE_UTIMENSAT
4537 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4538 UTIME_TO_TIMESPEC;
4539 return utimensat(dir_fd, path, time, flags);
4540#elif defined(HAVE_FUTIMESAT)
4541 UTIME_TO_TIMEVAL;
4542 /*
4543 * follow_symlinks will never be false here;
4544 * we only allow !follow_symlinks and dir_fd together
4545 * if we have utimensat()
4546 */
4547 assert(follow_symlinks);
4548 return futimesat(dir_fd, path, time);
4549#endif
4550}
4551
Larry Hastings2f936352014-08-05 14:04:04 +10004552 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4553#else
4554 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555#endif
4556
Victor Stinner528a9ab2015-09-03 21:30:26 +02004557#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558
4559static int
Victor Stinner484df002014-10-09 13:52:31 +02004560utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561{
4562#ifdef HAVE_FUTIMENS
4563 UTIME_TO_TIMESPEC;
4564 return futimens(fd, time);
4565#else
4566 UTIME_TO_TIMEVAL;
4567 return futimes(fd, time);
4568#endif
4569}
4570
Larry Hastings2f936352014-08-05 14:04:04 +10004571 #define PATH_UTIME_HAVE_FD 1
4572#else
4573 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574#endif
4575
Victor Stinner5ebae872015-09-22 01:29:33 +02004576#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4577# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4578#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579
Victor Stinner4552ced2015-09-21 22:37:15 +02004580#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581
4582static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004583utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584{
4585#ifdef HAVE_UTIMENSAT
4586 UTIME_TO_TIMESPEC;
4587 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4588#else
4589 UTIME_TO_TIMEVAL;
4590 return lutimes(path, time);
4591#endif
4592}
4593
4594#endif
4595
4596#ifndef MS_WINDOWS
4597
4598static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004599utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600{
4601#ifdef HAVE_UTIMENSAT
4602 UTIME_TO_TIMESPEC;
4603 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4604#elif defined(HAVE_UTIMES)
4605 UTIME_TO_TIMEVAL;
4606 return utimes(path, time);
4607#elif defined(HAVE_UTIME_H)
4608 UTIME_TO_UTIMBUF;
4609 return utime(path, time);
4610#else
4611 UTIME_TO_TIME_T;
4612 return utime(path, time);
4613#endif
4614}
4615
4616#endif
4617
Larry Hastings76ad59b2012-05-03 00:30:07 -07004618static int
4619split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4620{
4621 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004622 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004623 divmod = PyNumber_Divmod(py_long, billion);
4624 if (!divmod)
4625 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004626 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4627 PyErr_Format(PyExc_TypeError,
4628 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4629 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4630 goto exit;
4631 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004632 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4633 if ((*s == -1) && PyErr_Occurred())
4634 goto exit;
4635 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004636 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004637 goto exit;
4638
4639 result = 1;
4640exit:
4641 Py_XDECREF(divmod);
4642 return result;
4643}
4644
Larry Hastings2f936352014-08-05 14:04:04 +10004645
4646/*[clinic input]
4647os.utime
4648
4649 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4650 times: object = NULL
4651 *
4652 ns: object = NULL
4653 dir_fd: dir_fd(requires='futimensat') = None
4654 follow_symlinks: bool=True
4655
Martin Panter0ff89092015-09-09 01:56:53 +00004656# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004657
4658Set the access and modified time of path.
4659
4660path may always be specified as a string.
4661On some platforms, path may also be specified as an open file descriptor.
4662 If this functionality is unavailable, using it raises an exception.
4663
4664If times is not None, it must be a tuple (atime, mtime);
4665 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004666If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004667 atime_ns and mtime_ns should be expressed as integer nanoseconds
4668 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004669If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004670Specifying tuples for both times and ns is an error.
4671
4672If dir_fd is not None, it should be a file descriptor open to a directory,
4673 and path should be relative; path will then be relative to that directory.
4674If follow_symlinks is False, and the last element of the path is a symbolic
4675 link, utime will modify the symbolic link itself instead of the file the
4676 link points to.
4677It is an error to use dir_fd or follow_symlinks when specifying path
4678 as an open file descriptor.
4679dir_fd and follow_symlinks may not be available on your platform.
4680 If they are unavailable, using them will raise a NotImplementedError.
4681
4682[clinic start generated code]*/
4683
Larry Hastings2f936352014-08-05 14:04:04 +10004684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004685os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4686 int dir_fd, int follow_symlinks)
4687/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004688{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689#ifdef MS_WINDOWS
4690 HANDLE hFile;
4691 FILETIME atime, mtime;
4692#else
4693 int result;
4694#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004695
Larry Hastings2f936352014-08-05 14:04:04 +10004696 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697
Christian Heimesb3c87242013-08-01 00:08:16 +02004698 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004699
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700 if (times && (times != Py_None) && ns) {
4701 PyErr_SetString(PyExc_ValueError,
4702 "utime: you may specify either 'times'"
4703 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004704 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004705 }
4706
4707 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004708 time_t a_sec, m_sec;
4709 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004710 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004711 PyErr_SetString(PyExc_TypeError,
4712 "utime: 'times' must be either"
4713 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004714 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004715 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004717 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004718 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004719 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004720 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004721 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004722 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004723 utime.atime_s = a_sec;
4724 utime.atime_ns = a_nsec;
4725 utime.mtime_s = m_sec;
4726 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004727 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004728 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004729 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730 PyErr_SetString(PyExc_TypeError,
4731 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004732 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004733 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004735 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004737 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004739 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004740 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741 }
4742 else {
4743 /* times and ns are both None/unspecified. use "now". */
4744 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004745 }
4746
Victor Stinner4552ced2015-09-21 22:37:15 +02004747#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004749 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004751
Larry Hastings2f936352014-08-05 14:04:04 +10004752 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4753 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4754 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004755 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004756
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757#if !defined(HAVE_UTIMENSAT)
4758 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004759 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760 "utime: cannot use dir_fd and follow_symlinks "
4761 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004762 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 }
4764#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004765
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004766#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004768 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4769 NULL, OPEN_EXISTING,
4770 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771 Py_END_ALLOW_THREADS
4772 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004773 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004774 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004775 }
4776
Larry Hastings9cf065c2012-06-22 16:30:09 -07004777 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004778 GetSystemTimeAsFileTime(&mtime);
4779 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004782 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4783 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004784 }
4785 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4786 /* Avoid putting the file name into the error here,
4787 as that may confuse the user into believing that
4788 something is wrong with the file, when it also
4789 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004790 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004791 CloseHandle(hFile);
4792 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004794 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004795#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004796 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004797
Victor Stinner4552ced2015-09-21 22:37:15 +02004798#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004800 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004802#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803
Victor Stinner528a9ab2015-09-03 21:30:26 +02004804#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004805 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004806 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 else
4808#endif
4809
Victor Stinner528a9ab2015-09-03 21:30:26 +02004810#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004811 if (path->fd != -1)
4812 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813 else
4814#endif
4815
Larry Hastings2f936352014-08-05 14:04:04 +10004816 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004817
4818 Py_END_ALLOW_THREADS
4819
4820 if (result < 0) {
4821 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004822 posix_error();
4823 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004825
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004826#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004828 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004829}
4830
Guido van Rossum3b066191991-06-04 19:40:25 +00004831/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004832
Larry Hastings2f936352014-08-05 14:04:04 +10004833
4834/*[clinic input]
4835os._exit
4836
4837 status: int
4838
4839Exit to the system with specified status, without normal exit processing.
4840[clinic start generated code]*/
4841
Larry Hastings2f936352014-08-05 14:04:04 +10004842static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004843os__exit_impl(PyObject *module, int status)
4844/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004845{
4846 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004848}
4849
Steve Dowercc16be82016-09-08 10:35:16 -07004850#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4851#define EXECV_CHAR wchar_t
4852#else
4853#define EXECV_CHAR char
4854#endif
4855
Martin v. Löwis114619e2002-10-07 06:44:21 +00004856#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4857static void
Steve Dowercc16be82016-09-08 10:35:16 -07004858free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004859{
Victor Stinner8c62be82010-05-06 00:08:46 +00004860 Py_ssize_t i;
4861 for (i = 0; i < count; i++)
4862 PyMem_Free(array[i]);
4863 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004864}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004865
Berker Peksag81816462016-09-15 20:19:47 +03004866static int
4867fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004868{
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004870 PyObject *ub;
4871 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004872#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004873 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004874 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004875 *out = PyUnicode_AsWideCharString(ub, &size);
4876 if (*out)
4877 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004878#else
Berker Peksag81816462016-09-15 20:19:47 +03004879 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004881 size = PyBytes_GET_SIZE(ub);
4882 *out = PyMem_Malloc(size + 1);
4883 if (*out) {
4884 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4885 result = 1;
4886 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004887 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004888#endif
Berker Peksag81816462016-09-15 20:19:47 +03004889 Py_DECREF(ub);
4890 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004891}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004892#endif
4893
Ross Lagerwall7807c352011-03-17 20:20:30 +02004894#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004895static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004896parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4897{
Victor Stinner8c62be82010-05-06 00:08:46 +00004898 Py_ssize_t i, pos, envc;
4899 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004900 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004901 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 i = PyMapping_Size(env);
4904 if (i < 0)
4905 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004906 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004907 if (envlist == NULL) {
4908 PyErr_NoMemory();
4909 return NULL;
4910 }
4911 envc = 0;
4912 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004913 if (!keys)
4914 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004916 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004917 goto error;
4918 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4919 PyErr_Format(PyExc_TypeError,
4920 "env.keys() or env.values() is not a list");
4921 goto error;
4922 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004923
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 for (pos = 0; pos < i; pos++) {
4925 key = PyList_GetItem(keys, pos);
4926 val = PyList_GetItem(vals, pos);
4927 if (!key || !val)
4928 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004929
Berker Peksag81816462016-09-15 20:19:47 +03004930#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4931 if (!PyUnicode_FSDecoder(key, &key2))
4932 goto error;
4933 if (!PyUnicode_FSDecoder(val, &val2)) {
4934 Py_DECREF(key2);
4935 goto error;
4936 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004937 /* Search from index 1 because on Windows starting '=' is allowed for
4938 defining hidden environment variables. */
4939 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4940 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4941 {
4942 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004943 Py_DECREF(key2);
4944 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004945 goto error;
4946 }
Berker Peksag81816462016-09-15 20:19:47 +03004947 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4948#else
4949 if (!PyUnicode_FSConverter(key, &key2))
4950 goto error;
4951 if (!PyUnicode_FSConverter(val, &val2)) {
4952 Py_DECREF(key2);
4953 goto error;
4954 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004955 if (PyBytes_GET_SIZE(key2) == 0 ||
4956 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4957 {
4958 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004959 Py_DECREF(key2);
4960 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004961 goto error;
4962 }
Berker Peksag81816462016-09-15 20:19:47 +03004963 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4964 PyBytes_AS_STRING(val2));
4965#endif
4966 Py_DECREF(key2);
4967 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004968 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004970
4971 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4972 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 goto error;
4974 }
Berker Peksag81816462016-09-15 20:19:47 +03004975
Steve Dowercc16be82016-09-08 10:35:16 -07004976 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 }
4978 Py_DECREF(vals);
4979 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004980
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 envlist[envc] = 0;
4982 *envc_ptr = envc;
4983 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
4985error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 Py_XDECREF(keys);
4987 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004988 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004990}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004991
Steve Dowercc16be82016-09-08 10:35:16 -07004992static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004993parse_arglist(PyObject* argv, Py_ssize_t *argc)
4994{
4995 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004996 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 if (argvlist == NULL) {
4998 PyErr_NoMemory();
4999 return NULL;
5000 }
5001 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005002 PyObject* item = PySequence_ITEM(argv, i);
5003 if (item == NULL)
5004 goto fail;
5005 if (!fsconvert_strdup(item, &argvlist[i])) {
5006 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005007 goto fail;
5008 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005009 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005010 }
5011 argvlist[*argc] = NULL;
5012 return argvlist;
5013fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005014 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015 free_string_array(argvlist, *argc);
5016 return NULL;
5017}
Steve Dowercc16be82016-09-08 10:35:16 -07005018
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019#endif
5020
Larry Hastings2f936352014-08-05 14:04:04 +10005021
Ross Lagerwall7807c352011-03-17 20:20:30 +02005022#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005023/*[clinic input]
5024os.execv
5025
Steve Dowercc16be82016-09-08 10:35:16 -07005026 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005027 Path of executable file.
5028 argv: object
5029 Tuple or list of strings.
5030 /
5031
5032Execute an executable path with arguments, replacing current process.
5033[clinic start generated code]*/
5034
Larry Hastings2f936352014-08-05 14:04:04 +10005035static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005036os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5037/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005038{
Steve Dowercc16be82016-09-08 10:35:16 -07005039 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005040 Py_ssize_t argc;
5041
5042 /* execv has two arguments: (path, argv), where
5043 argv is a list or tuple of strings. */
5044
Ross Lagerwall7807c352011-03-17 20:20:30 +02005045 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5046 PyErr_SetString(PyExc_TypeError,
5047 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 return NULL;
5049 }
5050 argc = PySequence_Size(argv);
5051 if (argc < 1) {
5052 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 return NULL;
5054 }
5055
5056 argvlist = parse_arglist(argv, &argc);
5057 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005058 return NULL;
5059 }
Steve Dowerbce26262016-11-19 19:17:26 -08005060 if (!argvlist[0][0]) {
5061 PyErr_SetString(PyExc_ValueError,
5062 "execv() arg 2 first element cannot be empty");
5063 free_string_array(argvlist, argc);
5064 return NULL;
5065 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066
Steve Dowerbce26262016-11-19 19:17:26 -08005067 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005068#ifdef HAVE_WEXECV
5069 _wexecv(path->wide, argvlist);
5070#else
5071 execv(path->narrow, argvlist);
5072#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005073 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005074
5075 /* If we get here it's definitely an error */
5076
5077 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005078 return posix_error();
5079}
5080
Larry Hastings2f936352014-08-05 14:04:04 +10005081
5082/*[clinic input]
5083os.execve
5084
5085 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5086 Path of executable file.
5087 argv: object
5088 Tuple or list of strings.
5089 env: object
5090 Dictionary of strings mapping to strings.
5091
5092Execute an executable path with arguments, replacing current process.
5093[clinic start generated code]*/
5094
Larry Hastings2f936352014-08-05 14:04:04 +10005095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005096os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5097/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005098{
Steve Dowercc16be82016-09-08 10:35:16 -07005099 EXECV_CHAR **argvlist = NULL;
5100 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005101 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005102
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 /* execve has three arguments: (path, argv, env), where
5104 argv is a list or tuple of strings and env is a dictionary
5105 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005106
Ross Lagerwall7807c352011-03-17 20:20:30 +02005107 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005109 "execve: argv must be a tuple or list");
5110 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005112 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005113 if (argc < 1) {
5114 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5115 return NULL;
5116 }
5117
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 if (!PyMapping_Check(env)) {
5119 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005120 "execve: environment must be a mapping object");
5121 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005123
Ross Lagerwall7807c352011-03-17 20:20:30 +02005124 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005125 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005127 }
Steve Dowerbce26262016-11-19 19:17:26 -08005128 if (!argvlist[0][0]) {
5129 PyErr_SetString(PyExc_ValueError,
5130 "execve: argv first element cannot be empty");
5131 goto fail;
5132 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005133
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 envlist = parse_envlist(env, &envc);
5135 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005136 goto fail;
5137
Steve Dowerbce26262016-11-19 19:17:26 -08005138 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005139#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005140 if (path->fd > -1)
5141 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005142 else
5143#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005144#ifdef HAVE_WEXECV
5145 _wexecve(path->wide, argvlist, envlist);
5146#else
Larry Hastings2f936352014-08-05 14:04:04 +10005147 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005148#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005149 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005150
5151 /* If we get here it's definitely an error */
5152
Alexey Izbyshev83460312018-10-20 03:28:22 +03005153 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005154
Steve Dowercc16be82016-09-08 10:35:16 -07005155 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005156 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005157 if (argvlist)
5158 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005159 return NULL;
5160}
Steve Dowercc16be82016-09-08 10:35:16 -07005161
Larry Hastings9cf065c2012-06-22 16:30:09 -07005162#endif /* HAVE_EXECV */
5163
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005164#ifdef HAVE_POSIX_SPAWN
5165
5166enum posix_spawn_file_actions_identifier {
5167 POSIX_SPAWN_OPEN,
5168 POSIX_SPAWN_CLOSE,
5169 POSIX_SPAWN_DUP2
5170};
5171
William Orr81574b82018-10-01 22:19:56 -07005172#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005173static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005174convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005175#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005176
5177static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005178parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5179 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005180 PyObject *setsigdef, PyObject *scheduler,
5181 posix_spawnattr_t *attrp)
5182{
5183 long all_flags = 0;
5184
5185 errno = posix_spawnattr_init(attrp);
5186 if (errno) {
5187 posix_error();
5188 return -1;
5189 }
5190
5191 if (setpgroup) {
5192 pid_t pgid = PyLong_AsPid(setpgroup);
5193 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5194 goto fail;
5195 }
5196 errno = posix_spawnattr_setpgroup(attrp, pgid);
5197 if (errno) {
5198 posix_error();
5199 goto fail;
5200 }
5201 all_flags |= POSIX_SPAWN_SETPGROUP;
5202 }
5203
5204 if (resetids) {
5205 all_flags |= POSIX_SPAWN_RESETIDS;
5206 }
5207
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005208 if (setsid) {
5209#ifdef POSIX_SPAWN_SETSID
5210 all_flags |= POSIX_SPAWN_SETSID;
5211#elif defined(POSIX_SPAWN_SETSID_NP)
5212 all_flags |= POSIX_SPAWN_SETSID_NP;
5213#else
5214 argument_unavailable_error(func_name, "setsid");
5215 return -1;
5216#endif
5217 }
5218
Pablo Galindo254a4662018-09-07 16:44:24 +01005219 if (setsigmask) {
5220 sigset_t set;
5221 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5222 goto fail;
5223 }
5224 errno = posix_spawnattr_setsigmask(attrp, &set);
5225 if (errno) {
5226 posix_error();
5227 goto fail;
5228 }
5229 all_flags |= POSIX_SPAWN_SETSIGMASK;
5230 }
5231
5232 if (setsigdef) {
5233 sigset_t set;
5234 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5235 goto fail;
5236 }
5237 errno = posix_spawnattr_setsigdefault(attrp, &set);
5238 if (errno) {
5239 posix_error();
5240 goto fail;
5241 }
5242 all_flags |= POSIX_SPAWN_SETSIGDEF;
5243 }
5244
5245 if (scheduler) {
5246#ifdef POSIX_SPAWN_SETSCHEDULER
5247 PyObject *py_schedpolicy;
5248 struct sched_param schedparam;
5249
5250 if (!PyArg_ParseTuple(scheduler, "OO&"
5251 ";A scheduler tuple must have two elements",
5252 &py_schedpolicy, convert_sched_param, &schedparam)) {
5253 goto fail;
5254 }
5255 if (py_schedpolicy != Py_None) {
5256 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5257
5258 if (schedpolicy == -1 && PyErr_Occurred()) {
5259 goto fail;
5260 }
5261 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5262 if (errno) {
5263 posix_error();
5264 goto fail;
5265 }
5266 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5267 }
5268 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5269 if (errno) {
5270 posix_error();
5271 goto fail;
5272 }
5273 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5274#else
5275 PyErr_SetString(PyExc_NotImplementedError,
5276 "The scheduler option is not supported in this system.");
5277 goto fail;
5278#endif
5279 }
5280
5281 errno = posix_spawnattr_setflags(attrp, all_flags);
5282 if (errno) {
5283 posix_error();
5284 goto fail;
5285 }
5286
5287 return 0;
5288
5289fail:
5290 (void)posix_spawnattr_destroy(attrp);
5291 return -1;
5292}
5293
5294static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005295parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005296 posix_spawn_file_actions_t *file_actionsp,
5297 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005298{
5299 PyObject *seq;
5300 PyObject *file_action = NULL;
5301 PyObject *tag_obj;
5302
5303 seq = PySequence_Fast(file_actions,
5304 "file_actions must be a sequence or None");
5305 if (seq == NULL) {
5306 return -1;
5307 }
5308
5309 errno = posix_spawn_file_actions_init(file_actionsp);
5310 if (errno) {
5311 posix_error();
5312 Py_DECREF(seq);
5313 return -1;
5314 }
5315
5316 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5317 file_action = PySequence_Fast_GET_ITEM(seq, i);
5318 Py_INCREF(file_action);
5319 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5320 PyErr_SetString(PyExc_TypeError,
5321 "Each file_actions element must be a non-empty tuple");
5322 goto fail;
5323 }
5324 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5325 if (tag == -1 && PyErr_Occurred()) {
5326 goto fail;
5327 }
5328
5329 /* Populate the file_actions object */
5330 switch (tag) {
5331 case POSIX_SPAWN_OPEN: {
5332 int fd, oflag;
5333 PyObject *path;
5334 unsigned long mode;
5335 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5336 ";A open file_action tuple must have 5 elements",
5337 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5338 &oflag, &mode))
5339 {
5340 goto fail;
5341 }
Pablo Galindocb970732018-06-19 09:19:50 +01005342 if (PyList_Append(temp_buffer, path)) {
5343 Py_DECREF(path);
5344 goto fail;
5345 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005346 errno = posix_spawn_file_actions_addopen(file_actionsp,
5347 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005348 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005349 if (errno) {
5350 posix_error();
5351 goto fail;
5352 }
5353 break;
5354 }
5355 case POSIX_SPAWN_CLOSE: {
5356 int fd;
5357 if (!PyArg_ParseTuple(file_action, "Oi"
5358 ";A close file_action tuple must have 2 elements",
5359 &tag_obj, &fd))
5360 {
5361 goto fail;
5362 }
5363 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5364 if (errno) {
5365 posix_error();
5366 goto fail;
5367 }
5368 break;
5369 }
5370 case POSIX_SPAWN_DUP2: {
5371 int fd1, fd2;
5372 if (!PyArg_ParseTuple(file_action, "Oii"
5373 ";A dup2 file_action tuple must have 3 elements",
5374 &tag_obj, &fd1, &fd2))
5375 {
5376 goto fail;
5377 }
5378 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5379 fd1, fd2);
5380 if (errno) {
5381 posix_error();
5382 goto fail;
5383 }
5384 break;
5385 }
5386 default: {
5387 PyErr_SetString(PyExc_TypeError,
5388 "Unknown file_actions identifier");
5389 goto fail;
5390 }
5391 }
5392 Py_DECREF(file_action);
5393 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005394
Serhiy Storchakaef347532018-05-01 16:45:04 +03005395 Py_DECREF(seq);
5396 return 0;
5397
5398fail:
5399 Py_DECREF(seq);
5400 Py_DECREF(file_action);
5401 (void)posix_spawn_file_actions_destroy(file_actionsp);
5402 return -1;
5403}
5404
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005405
5406static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005407py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5408 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005409 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005410 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005411{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005412 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005413 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005414 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005415 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005416 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005417 posix_spawnattr_t attr;
5418 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005419 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005420 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005421 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005422 pid_t pid;
5423 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005424
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005425 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005426 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005427 like posix.environ. */
5428
Serhiy Storchakaef347532018-05-01 16:45:04 +03005429 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005430 PyErr_Format(PyExc_TypeError,
5431 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005432 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005433 }
5434 argc = PySequence_Size(argv);
5435 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005436 PyErr_Format(PyExc_ValueError,
5437 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005438 return NULL;
5439 }
5440
5441 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005442 PyErr_Format(PyExc_TypeError,
5443 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005444 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005445 }
5446
5447 argvlist = parse_arglist(argv, &argc);
5448 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005449 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005450 }
5451 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005452 PyErr_Format(PyExc_ValueError,
5453 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005454 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005455 }
5456
5457 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005458 if (envlist == NULL) {
5459 goto exit;
5460 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005461
Serhiy Storchakad700f972018-09-08 14:48:18 +03005462 if (file_actions != NULL) {
Pablo Galindocb970732018-06-19 09:19:50 +01005463 /* There is a bug in old versions of glibc that makes some of the
5464 * helper functions for manipulating file actions not copy the provided
5465 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5466 * copy the value of path for some old versions of glibc (<2.20).
5467 * The use of temp_buffer here is a workaround that keeps the
5468 * python objects that own the buffers alive until posix_spawn gets called.
5469 * Check https://bugs.python.org/issue33630 and
5470 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5471 temp_buffer = PyList_New(0);
5472 if (!temp_buffer) {
5473 goto exit;
5474 }
5475 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005476 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005477 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005478 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005479 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005480
Victor Stinner325e4ba2019-02-01 15:47:24 +01005481 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5482 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005483 goto exit;
5484 }
5485 attrp = &attr;
5486
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005487 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005488#ifdef HAVE_POSIX_SPAWNP
5489 if (use_posix_spawnp) {
5490 err_code = posix_spawnp(&pid, path->narrow,
5491 file_actionsp, attrp, argvlist, envlist);
5492 }
5493 else
5494#endif /* HAVE_POSIX_SPAWNP */
5495 {
5496 err_code = posix_spawn(&pid, path->narrow,
5497 file_actionsp, attrp, argvlist, envlist);
5498 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005499 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005500
Serhiy Storchakaef347532018-05-01 16:45:04 +03005501 if (err_code) {
5502 errno = err_code;
5503 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005504 goto exit;
5505 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005506#ifdef _Py_MEMORY_SANITIZER
5507 __msan_unpoison(&pid, sizeof(pid));
5508#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005509 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005510
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005511exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005512 if (file_actionsp) {
5513 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005514 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005515 if (attrp) {
5516 (void)posix_spawnattr_destroy(attrp);
5517 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005518 if (envlist) {
5519 free_string_array(envlist, envc);
5520 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005521 if (argvlist) {
5522 free_string_array(argvlist, argc);
5523 }
Pablo Galindocb970732018-06-19 09:19:50 +01005524 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005525 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005526}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005527
5528
5529/*[clinic input]
5530
5531os.posix_spawn
5532 path: path_t
5533 Path of executable file.
5534 argv: object
5535 Tuple or list of strings.
5536 env: object
5537 Dictionary of strings mapping to strings.
5538 /
5539 *
5540 file_actions: object(c_default='NULL') = ()
5541 A sequence of file action tuples.
5542 setpgroup: object = NULL
5543 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5544 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005545 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5546 setsid: bool(accept={int}) = False
5547 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005548 setsigmask: object(c_default='NULL') = ()
5549 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5550 setsigdef: object(c_default='NULL') = ()
5551 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5552 scheduler: object = NULL
5553 A tuple with the scheduler policy (optional) and parameters.
5554
5555Execute the program specified by path in a new process.
5556[clinic start generated code]*/
5557
5558static PyObject *
5559os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5560 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005561 PyObject *setpgroup, int resetids, int setsid,
5562 PyObject *setsigmask, PyObject *setsigdef,
5563 PyObject *scheduler)
5564/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005565{
5566 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005567 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005568 scheduler);
5569}
5570 #endif /* HAVE_POSIX_SPAWN */
5571
5572
5573
5574#ifdef HAVE_POSIX_SPAWNP
5575/*[clinic input]
5576
5577os.posix_spawnp
5578 path: path_t
5579 Path of executable file.
5580 argv: object
5581 Tuple or list of strings.
5582 env: object
5583 Dictionary of strings mapping to strings.
5584 /
5585 *
5586 file_actions: object(c_default='NULL') = ()
5587 A sequence of file action tuples.
5588 setpgroup: object = NULL
5589 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5590 resetids: bool(accept={int}) = False
5591 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005592 setsid: bool(accept={int}) = False
5593 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005594 setsigmask: object(c_default='NULL') = ()
5595 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5596 setsigdef: object(c_default='NULL') = ()
5597 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5598 scheduler: object = NULL
5599 A tuple with the scheduler policy (optional) and parameters.
5600
5601Execute the program specified by path in a new process.
5602[clinic start generated code]*/
5603
5604static PyObject *
5605os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5606 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005607 PyObject *setpgroup, int resetids, int setsid,
5608 PyObject *setsigmask, PyObject *setsigdef,
5609 PyObject *scheduler)
5610/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005611{
5612 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005613 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005614 scheduler);
5615}
5616#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005617
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005618
Steve Dowercc16be82016-09-08 10:35:16 -07005619#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005620/*[clinic input]
5621os.spawnv
5622
5623 mode: int
5624 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005625 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005626 Path of executable file.
5627 argv: object
5628 Tuple or list of strings.
5629 /
5630
5631Execute the program specified by path in a new process.
5632[clinic start generated code]*/
5633
Larry Hastings2f936352014-08-05 14:04:04 +10005634static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005635os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5636/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005637{
Steve Dowercc16be82016-09-08 10:35:16 -07005638 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005639 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005640 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005641 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005642 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005643
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 /* spawnv has three arguments: (mode, path, argv), where
5645 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005646
Victor Stinner8c62be82010-05-06 00:08:46 +00005647 if (PyList_Check(argv)) {
5648 argc = PyList_Size(argv);
5649 getitem = PyList_GetItem;
5650 }
5651 else if (PyTuple_Check(argv)) {
5652 argc = PyTuple_Size(argv);
5653 getitem = PyTuple_GetItem;
5654 }
5655 else {
5656 PyErr_SetString(PyExc_TypeError,
5657 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005658 return NULL;
5659 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005660 if (argc == 0) {
5661 PyErr_SetString(PyExc_ValueError,
5662 "spawnv() arg 2 cannot be empty");
5663 return NULL;
5664 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005665
Steve Dowercc16be82016-09-08 10:35:16 -07005666 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005667 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005668 return PyErr_NoMemory();
5669 }
5670 for (i = 0; i < argc; i++) {
5671 if (!fsconvert_strdup((*getitem)(argv, i),
5672 &argvlist[i])) {
5673 free_string_array(argvlist, i);
5674 PyErr_SetString(
5675 PyExc_TypeError,
5676 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005677 return NULL;
5678 }
Steve Dower93ff8722016-11-19 19:03:54 -08005679 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005680 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005681 PyErr_SetString(
5682 PyExc_ValueError,
5683 "spawnv() arg 2 first element cannot be empty");
5684 return NULL;
5685 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005686 }
5687 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005688
Victor Stinner8c62be82010-05-06 00:08:46 +00005689 if (mode == _OLD_P_OVERLAY)
5690 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005691
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005693 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005694#ifdef HAVE_WSPAWNV
5695 spawnval = _wspawnv(mode, path->wide, argvlist);
5696#else
5697 spawnval = _spawnv(mode, path->narrow, argvlist);
5698#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005699 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005700 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005701
Victor Stinner8c62be82010-05-06 00:08:46 +00005702 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005703
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 if (spawnval == -1)
5705 return posix_error();
5706 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005707 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005708}
5709
Larry Hastings2f936352014-08-05 14:04:04 +10005710/*[clinic input]
5711os.spawnve
5712
5713 mode: int
5714 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005715 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005716 Path of executable file.
5717 argv: object
5718 Tuple or list of strings.
5719 env: object
5720 Dictionary of strings mapping to strings.
5721 /
5722
5723Execute the program specified by path in a new process.
5724[clinic start generated code]*/
5725
Larry Hastings2f936352014-08-05 14:04:04 +10005726static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005727os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005728 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005729/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005730{
Steve Dowercc16be82016-09-08 10:35:16 -07005731 EXECV_CHAR **argvlist;
5732 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005733 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005734 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005735 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005737 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005738
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 /* spawnve has four arguments: (mode, path, argv, env), where
5740 argv is a list or tuple of strings and env is a dictionary
5741 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005742
Victor Stinner8c62be82010-05-06 00:08:46 +00005743 if (PyList_Check(argv)) {
5744 argc = PyList_Size(argv);
5745 getitem = PyList_GetItem;
5746 }
5747 else if (PyTuple_Check(argv)) {
5748 argc = PyTuple_Size(argv);
5749 getitem = PyTuple_GetItem;
5750 }
5751 else {
5752 PyErr_SetString(PyExc_TypeError,
5753 "spawnve() arg 2 must be a tuple or list");
5754 goto fail_0;
5755 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005756 if (argc == 0) {
5757 PyErr_SetString(PyExc_ValueError,
5758 "spawnve() arg 2 cannot be empty");
5759 goto fail_0;
5760 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005761 if (!PyMapping_Check(env)) {
5762 PyErr_SetString(PyExc_TypeError,
5763 "spawnve() arg 3 must be a mapping object");
5764 goto fail_0;
5765 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005766
Steve Dowercc16be82016-09-08 10:35:16 -07005767 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005768 if (argvlist == NULL) {
5769 PyErr_NoMemory();
5770 goto fail_0;
5771 }
5772 for (i = 0; i < argc; i++) {
5773 if (!fsconvert_strdup((*getitem)(argv, i),
5774 &argvlist[i]))
5775 {
5776 lastarg = i;
5777 goto fail_1;
5778 }
Steve Dowerbce26262016-11-19 19:17:26 -08005779 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005780 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005781 PyErr_SetString(
5782 PyExc_ValueError,
5783 "spawnv() arg 2 first element cannot be empty");
5784 goto fail_1;
5785 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 }
5787 lastarg = argc;
5788 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005789
Victor Stinner8c62be82010-05-06 00:08:46 +00005790 envlist = parse_envlist(env, &envc);
5791 if (envlist == NULL)
5792 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005793
Victor Stinner8c62be82010-05-06 00:08:46 +00005794 if (mode == _OLD_P_OVERLAY)
5795 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005796
Victor Stinner8c62be82010-05-06 00:08:46 +00005797 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005798 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005799#ifdef HAVE_WSPAWNV
5800 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5801#else
5802 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5803#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005804 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005806
Victor Stinner8c62be82010-05-06 00:08:46 +00005807 if (spawnval == -1)
5808 (void) posix_error();
5809 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005810 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005811
Victor Stinner8c62be82010-05-06 00:08:46 +00005812 while (--envc >= 0)
5813 PyMem_DEL(envlist[envc]);
5814 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005815 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005816 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005817 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005819}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005820
Guido van Rossuma1065681999-01-25 23:20:23 +00005821#endif /* HAVE_SPAWNV */
5822
5823
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005824#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005825
5826/* Helper function to validate arguments.
5827 Returns 0 on success. non-zero on failure with a TypeError raised.
5828 If obj is non-NULL it must be callable. */
5829static int
5830check_null_or_callable(PyObject *obj, const char* obj_name)
5831{
5832 if (obj && !PyCallable_Check(obj)) {
5833 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5834 obj_name, Py_TYPE(obj)->tp_name);
5835 return -1;
5836 }
5837 return 0;
5838}
5839
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005840/*[clinic input]
5841os.register_at_fork
5842
Gregory P. Smith163468a2017-05-29 10:03:41 -07005843 *
5844 before: object=NULL
5845 A callable to be called in the parent before the fork() syscall.
5846 after_in_child: object=NULL
5847 A callable to be called in the child after fork().
5848 after_in_parent: object=NULL
5849 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005850
Gregory P. Smith163468a2017-05-29 10:03:41 -07005851Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005852
Gregory P. Smith163468a2017-05-29 10:03:41 -07005853'before' callbacks are called in reverse order.
5854'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005855
5856[clinic start generated code]*/
5857
5858static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005859os_register_at_fork_impl(PyObject *module, PyObject *before,
5860 PyObject *after_in_child, PyObject *after_in_parent)
5861/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005862{
5863 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005864
Gregory P. Smith163468a2017-05-29 10:03:41 -07005865 if (!before && !after_in_child && !after_in_parent) {
5866 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5867 return NULL;
5868 }
5869 if (check_null_or_callable(before, "before") ||
5870 check_null_or_callable(after_in_child, "after_in_child") ||
5871 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005872 return NULL;
5873 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005874 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005875
Gregory P. Smith163468a2017-05-29 10:03:41 -07005876 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005877 return NULL;
5878 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005879 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005880 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005881 }
5882 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5883 return NULL;
5884 }
5885 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005886}
5887#endif /* HAVE_FORK */
5888
5889
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005890#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005891/*[clinic input]
5892os.fork1
5893
5894Fork a child process with a single multiplexed (i.e., not bound) thread.
5895
5896Return 0 to child process and PID of child to parent process.
5897[clinic start generated code]*/
5898
Larry Hastings2f936352014-08-05 14:04:04 +10005899static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005900os_fork1_impl(PyObject *module)
5901/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005902{
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005904
Eric Snow59032962018-09-14 14:17:20 -07005905 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5906 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5907 return NULL;
5908 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005909 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 pid = fork1();
5911 if (pid == 0) {
5912 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005913 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 } else {
5915 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005916 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 }
5918 if (pid == -1)
5919 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005921}
Larry Hastings2f936352014-08-05 14:04:04 +10005922#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005923
5924
Guido van Rossumad0ee831995-03-01 10:34:45 +00005925#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005926/*[clinic input]
5927os.fork
5928
5929Fork a child process.
5930
5931Return 0 to child process and PID of child to parent process.
5932[clinic start generated code]*/
5933
Larry Hastings2f936352014-08-05 14:04:04 +10005934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005935os_fork_impl(PyObject *module)
5936/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005937{
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005939
Eric Snow59032962018-09-14 14:17:20 -07005940 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5941 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5942 return NULL;
5943 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005944 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 pid = fork();
5946 if (pid == 0) {
5947 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005948 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 } else {
5950 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005951 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 }
5953 if (pid == -1)
5954 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005956}
Larry Hastings2f936352014-08-05 14:04:04 +10005957#endif /* HAVE_FORK */
5958
Guido van Rossum85e3b011991-06-03 12:42:10 +00005959
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005960#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005961#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005962/*[clinic input]
5963os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005964
Larry Hastings2f936352014-08-05 14:04:04 +10005965 policy: int
5966
5967Get the maximum scheduling priority for policy.
5968[clinic start generated code]*/
5969
Larry Hastings2f936352014-08-05 14:04:04 +10005970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005971os_sched_get_priority_max_impl(PyObject *module, int policy)
5972/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005973{
5974 int max;
5975
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005976 max = sched_get_priority_max(policy);
5977 if (max < 0)
5978 return posix_error();
5979 return PyLong_FromLong(max);
5980}
5981
Larry Hastings2f936352014-08-05 14:04:04 +10005982
5983/*[clinic input]
5984os.sched_get_priority_min
5985
5986 policy: int
5987
5988Get the minimum scheduling priority for policy.
5989[clinic start generated code]*/
5990
Larry Hastings2f936352014-08-05 14:04:04 +10005991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005992os_sched_get_priority_min_impl(PyObject *module, int policy)
5993/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005994{
5995 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005996 if (min < 0)
5997 return posix_error();
5998 return PyLong_FromLong(min);
5999}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006000#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6001
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006002
Larry Hastings2f936352014-08-05 14:04:04 +10006003#ifdef HAVE_SCHED_SETSCHEDULER
6004/*[clinic input]
6005os.sched_getscheduler
6006 pid: pid_t
6007 /
6008
6009Get the scheduling policy for the process identifiedy by pid.
6010
6011Passing 0 for pid returns the scheduling policy for the calling process.
6012[clinic start generated code]*/
6013
Larry Hastings2f936352014-08-05 14:04:04 +10006014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006015os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6016/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006017{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006018 int policy;
6019
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006020 policy = sched_getscheduler(pid);
6021 if (policy < 0)
6022 return posix_error();
6023 return PyLong_FromLong(policy);
6024}
Larry Hastings2f936352014-08-05 14:04:04 +10006025#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006026
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006027
William Orr81574b82018-10-01 22:19:56 -07006028#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006029/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006030class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006031
6032@classmethod
6033os.sched_param.__new__
6034
6035 sched_priority: object
6036 A scheduling parameter.
6037
6038Current has only one field: sched_priority");
6039[clinic start generated code]*/
6040
Larry Hastings2f936352014-08-05 14:04:04 +10006041static PyObject *
6042os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006043/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006044{
6045 PyObject *res;
6046
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006047 res = PyStructSequence_New(type);
6048 if (!res)
6049 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006050 Py_INCREF(sched_priority);
6051 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006052 return res;
6053}
6054
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006055
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006056PyDoc_VAR(os_sched_param__doc__);
6057
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006058static PyStructSequence_Field sched_param_fields[] = {
6059 {"sched_priority", "the scheduling priority"},
6060 {0}
6061};
6062
6063static PyStructSequence_Desc sched_param_desc = {
6064 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006065 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006066 sched_param_fields,
6067 1
6068};
6069
6070static int
6071convert_sched_param(PyObject *param, struct sched_param *res)
6072{
6073 long priority;
6074
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006075 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006076 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6077 return 0;
6078 }
6079 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6080 if (priority == -1 && PyErr_Occurred())
6081 return 0;
6082 if (priority > INT_MAX || priority < INT_MIN) {
6083 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6084 return 0;
6085 }
6086 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6087 return 1;
6088}
William Orr81574b82018-10-01 22:19:56 -07006089#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006090
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006091
6092#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006093/*[clinic input]
6094os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006095
Larry Hastings2f936352014-08-05 14:04:04 +10006096 pid: pid_t
6097 policy: int
6098 param: sched_param
6099 /
6100
6101Set the scheduling policy for the process identified by pid.
6102
6103If pid is 0, the calling process is changed.
6104param is an instance of sched_param.
6105[clinic start generated code]*/
6106
Larry Hastings2f936352014-08-05 14:04:04 +10006107static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006108os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006109 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006110/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006111{
Jesus Cea9c822272011-09-10 01:40:52 +02006112 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006113 ** sched_setscheduler() returns 0 in Linux, but the previous
6114 ** scheduling policy under Solaris/Illumos, and others.
6115 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006116 */
Larry Hastings2f936352014-08-05 14:04:04 +10006117 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006118 return posix_error();
6119 Py_RETURN_NONE;
6120}
Larry Hastings2f936352014-08-05 14:04:04 +10006121#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006122
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006123
6124#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006125/*[clinic input]
6126os.sched_getparam
6127 pid: pid_t
6128 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006129
Larry Hastings2f936352014-08-05 14:04:04 +10006130Returns scheduling parameters for the process identified by pid.
6131
6132If pid is 0, returns parameters for the calling process.
6133Return value is an instance of sched_param.
6134[clinic start generated code]*/
6135
Larry Hastings2f936352014-08-05 14:04:04 +10006136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006137os_sched_getparam_impl(PyObject *module, pid_t pid)
6138/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006139{
6140 struct sched_param param;
6141 PyObject *result;
6142 PyObject *priority;
6143
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006144 if (sched_getparam(pid, &param))
6145 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006146 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006147 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006148 return NULL;
6149 priority = PyLong_FromLong(param.sched_priority);
6150 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006151 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006152 return NULL;
6153 }
Larry Hastings2f936352014-08-05 14:04:04 +10006154 PyStructSequence_SET_ITEM(result, 0, priority);
6155 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006156}
6157
Larry Hastings2f936352014-08-05 14:04:04 +10006158
6159/*[clinic input]
6160os.sched_setparam
6161 pid: pid_t
6162 param: sched_param
6163 /
6164
6165Set scheduling parameters for the process identified by pid.
6166
6167If pid is 0, sets parameters for the calling process.
6168param should be an instance of sched_param.
6169[clinic start generated code]*/
6170
Larry Hastings2f936352014-08-05 14:04:04 +10006171static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006172os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006173 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006174/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006175{
6176 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006177 return posix_error();
6178 Py_RETURN_NONE;
6179}
Larry Hastings2f936352014-08-05 14:04:04 +10006180#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006181
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006182
6183#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006184/*[clinic input]
6185os.sched_rr_get_interval -> double
6186 pid: pid_t
6187 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006188
Larry Hastings2f936352014-08-05 14:04:04 +10006189Return the round-robin quantum for the process identified by pid, in seconds.
6190
6191Value returned is a float.
6192[clinic start generated code]*/
6193
Larry Hastings2f936352014-08-05 14:04:04 +10006194static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006195os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6196/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006197{
6198 struct timespec interval;
6199 if (sched_rr_get_interval(pid, &interval)) {
6200 posix_error();
6201 return -1.0;
6202 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006203#ifdef _Py_MEMORY_SANITIZER
6204 __msan_unpoison(&interval, sizeof(interval));
6205#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006206 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6207}
6208#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006209
Larry Hastings2f936352014-08-05 14:04:04 +10006210
6211/*[clinic input]
6212os.sched_yield
6213
6214Voluntarily relinquish the CPU.
6215[clinic start generated code]*/
6216
Larry Hastings2f936352014-08-05 14:04:04 +10006217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006218os_sched_yield_impl(PyObject *module)
6219/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006220{
6221 if (sched_yield())
6222 return posix_error();
6223 Py_RETURN_NONE;
6224}
6225
Benjamin Peterson2740af82011-08-02 17:41:34 -05006226#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006227/* The minimum number of CPUs allocated in a cpu_set_t */
6228static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006229
Larry Hastings2f936352014-08-05 14:04:04 +10006230/*[clinic input]
6231os.sched_setaffinity
6232 pid: pid_t
6233 mask : object
6234 /
6235
6236Set the CPU affinity of the process identified by pid to mask.
6237
6238mask should be an iterable of integers identifying CPUs.
6239[clinic start generated code]*/
6240
Larry Hastings2f936352014-08-05 14:04:04 +10006241static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006242os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6243/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006244{
Antoine Pitrou84869872012-08-04 16:16:35 +02006245 int ncpus;
6246 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006247 cpu_set_t *cpu_set = NULL;
6248 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006249
Larry Hastings2f936352014-08-05 14:04:04 +10006250 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006251 if (iterator == NULL)
6252 return NULL;
6253
6254 ncpus = NCPUS_START;
6255 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006256 cpu_set = CPU_ALLOC(ncpus);
6257 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006258 PyErr_NoMemory();
6259 goto error;
6260 }
Larry Hastings2f936352014-08-05 14:04:04 +10006261 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006262
6263 while ((item = PyIter_Next(iterator))) {
6264 long cpu;
6265 if (!PyLong_Check(item)) {
6266 PyErr_Format(PyExc_TypeError,
6267 "expected an iterator of ints, "
6268 "but iterator yielded %R",
6269 Py_TYPE(item));
6270 Py_DECREF(item);
6271 goto error;
6272 }
6273 cpu = PyLong_AsLong(item);
6274 Py_DECREF(item);
6275 if (cpu < 0) {
6276 if (!PyErr_Occurred())
6277 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6278 goto error;
6279 }
6280 if (cpu > INT_MAX - 1) {
6281 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6282 goto error;
6283 }
6284 if (cpu >= ncpus) {
6285 /* Grow CPU mask to fit the CPU number */
6286 int newncpus = ncpus;
6287 cpu_set_t *newmask;
6288 size_t newsetsize;
6289 while (newncpus <= cpu) {
6290 if (newncpus > INT_MAX / 2)
6291 newncpus = cpu + 1;
6292 else
6293 newncpus = newncpus * 2;
6294 }
6295 newmask = CPU_ALLOC(newncpus);
6296 if (newmask == NULL) {
6297 PyErr_NoMemory();
6298 goto error;
6299 }
6300 newsetsize = CPU_ALLOC_SIZE(newncpus);
6301 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006302 memcpy(newmask, cpu_set, setsize);
6303 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006304 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006305 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006306 ncpus = newncpus;
6307 }
Larry Hastings2f936352014-08-05 14:04:04 +10006308 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006309 }
6310 Py_CLEAR(iterator);
6311
Larry Hastings2f936352014-08-05 14:04:04 +10006312 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006313 posix_error();
6314 goto error;
6315 }
Larry Hastings2f936352014-08-05 14:04:04 +10006316 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006317 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006318
6319error:
Larry Hastings2f936352014-08-05 14:04:04 +10006320 if (cpu_set)
6321 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006322 Py_XDECREF(iterator);
6323 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006324}
6325
Larry Hastings2f936352014-08-05 14:04:04 +10006326
6327/*[clinic input]
6328os.sched_getaffinity
6329 pid: pid_t
6330 /
6331
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006332Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006333
6334The affinity is returned as a set of CPU identifiers.
6335[clinic start generated code]*/
6336
Larry Hastings2f936352014-08-05 14:04:04 +10006337static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006338os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006339/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006340{
Antoine Pitrou84869872012-08-04 16:16:35 +02006341 int cpu, ncpus, count;
6342 size_t setsize;
6343 cpu_set_t *mask = NULL;
6344 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006345
Antoine Pitrou84869872012-08-04 16:16:35 +02006346 ncpus = NCPUS_START;
6347 while (1) {
6348 setsize = CPU_ALLOC_SIZE(ncpus);
6349 mask = CPU_ALLOC(ncpus);
6350 if (mask == NULL)
6351 return PyErr_NoMemory();
6352 if (sched_getaffinity(pid, setsize, mask) == 0)
6353 break;
6354 CPU_FREE(mask);
6355 if (errno != EINVAL)
6356 return posix_error();
6357 if (ncpus > INT_MAX / 2) {
6358 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6359 "a large enough CPU set");
6360 return NULL;
6361 }
6362 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006363 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006364
6365 res = PySet_New(NULL);
6366 if (res == NULL)
6367 goto error;
6368 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6369 if (CPU_ISSET_S(cpu, setsize, mask)) {
6370 PyObject *cpu_num = PyLong_FromLong(cpu);
6371 --count;
6372 if (cpu_num == NULL)
6373 goto error;
6374 if (PySet_Add(res, cpu_num)) {
6375 Py_DECREF(cpu_num);
6376 goto error;
6377 }
6378 Py_DECREF(cpu_num);
6379 }
6380 }
6381 CPU_FREE(mask);
6382 return res;
6383
6384error:
6385 if (mask)
6386 CPU_FREE(mask);
6387 Py_XDECREF(res);
6388 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006389}
6390
Benjamin Peterson2740af82011-08-02 17:41:34 -05006391#endif /* HAVE_SCHED_SETAFFINITY */
6392
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006393#endif /* HAVE_SCHED_H */
6394
Larry Hastings2f936352014-08-05 14:04:04 +10006395
Neal Norwitzb59798b2003-03-21 01:43:31 +00006396/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006397/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6398#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006399#define DEV_PTY_FILE "/dev/ptc"
6400#define HAVE_DEV_PTMX
6401#else
6402#define DEV_PTY_FILE "/dev/ptmx"
6403#endif
6404
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006405#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006406#ifdef HAVE_PTY_H
6407#include <pty.h>
6408#else
6409#ifdef HAVE_LIBUTIL_H
6410#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006411#else
6412#ifdef HAVE_UTIL_H
6413#include <util.h>
6414#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006415#endif /* HAVE_LIBUTIL_H */
6416#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006417#ifdef HAVE_STROPTS_H
6418#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006419#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006420#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006421
Larry Hastings2f936352014-08-05 14:04:04 +10006422
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006423#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006424/*[clinic input]
6425os.openpty
6426
6427Open a pseudo-terminal.
6428
6429Return a tuple of (master_fd, slave_fd) containing open file descriptors
6430for both the master and slave ends.
6431[clinic start generated code]*/
6432
Larry Hastings2f936352014-08-05 14:04:04 +10006433static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006434os_openpty_impl(PyObject *module)
6435/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006436{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006437 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006438#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006440#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006441#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006443#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006445#endif
6446#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006447
Thomas Wouters70c21a12000-07-14 14:28:33 +00006448#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006450 goto posix_error;
6451
6452 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6453 goto error;
6454 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6455 goto error;
6456
Neal Norwitzb59798b2003-03-21 01:43:31 +00006457#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6459 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006460 goto posix_error;
6461 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6462 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006463
Victor Stinnerdaf45552013-08-28 00:53:59 +02006464 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006466 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006467
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006468#else
Victor Stinner000de532013-11-25 23:19:58 +01006469 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006471 goto posix_error;
6472
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006474
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 /* change permission of slave */
6476 if (grantpt(master_fd) < 0) {
6477 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006478 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006479 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006480
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 /* unlock slave */
6482 if (unlockpt(master_fd) < 0) {
6483 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006484 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006486
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006488
Victor Stinner8c62be82010-05-06 00:08:46 +00006489 slave_name = ptsname(master_fd); /* get name of slave */
6490 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006491 goto posix_error;
6492
6493 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006494 if (slave_fd == -1)
6495 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006496
6497 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6498 goto posix_error;
6499
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006500#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006501 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6502 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006503#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006504 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006505#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006506#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006507#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006508
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006510
Victor Stinnerdaf45552013-08-28 00:53:59 +02006511posix_error:
6512 posix_error();
6513error:
6514 if (master_fd != -1)
6515 close(master_fd);
6516 if (slave_fd != -1)
6517 close(slave_fd);
6518 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006519}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006520#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006521
Larry Hastings2f936352014-08-05 14:04:04 +10006522
Fred Drake8cef4cf2000-06-28 16:40:38 +00006523#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006524/*[clinic input]
6525os.forkpty
6526
6527Fork a new process with a new pseudo-terminal as controlling tty.
6528
6529Returns a tuple of (pid, master_fd).
6530Like fork(), return pid of 0 to the child process,
6531and pid of child to the parent process.
6532To both, return fd of newly opened pseudo-terminal.
6533[clinic start generated code]*/
6534
Larry Hastings2f936352014-08-05 14:04:04 +10006535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006536os_forkpty_impl(PyObject *module)
6537/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006538{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006539 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006541
Eric Snow59032962018-09-14 14:17:20 -07006542 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6543 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6544 return NULL;
6545 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006546 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 pid = forkpty(&master_fd, NULL, NULL, NULL);
6548 if (pid == 0) {
6549 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006550 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 } else {
6552 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006553 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 }
6555 if (pid == -1)
6556 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006558}
Larry Hastings2f936352014-08-05 14:04:04 +10006559#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006560
Ross Lagerwall7807c352011-03-17 20:20:30 +02006561
Guido van Rossumad0ee831995-03-01 10:34:45 +00006562#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006563/*[clinic input]
6564os.getegid
6565
6566Return the current process's effective group id.
6567[clinic start generated code]*/
6568
Larry Hastings2f936352014-08-05 14:04:04 +10006569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006570os_getegid_impl(PyObject *module)
6571/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006572{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006573 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006574}
Larry Hastings2f936352014-08-05 14:04:04 +10006575#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006576
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006577
Guido van Rossumad0ee831995-03-01 10:34:45 +00006578#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006579/*[clinic input]
6580os.geteuid
6581
6582Return the current process's effective user id.
6583[clinic start generated code]*/
6584
Larry Hastings2f936352014-08-05 14:04:04 +10006585static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006586os_geteuid_impl(PyObject *module)
6587/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006588{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006589 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006590}
Larry Hastings2f936352014-08-05 14:04:04 +10006591#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006593
Guido van Rossumad0ee831995-03-01 10:34:45 +00006594#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006595/*[clinic input]
6596os.getgid
6597
6598Return the current process's group id.
6599[clinic start generated code]*/
6600
Larry Hastings2f936352014-08-05 14:04:04 +10006601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006602os_getgid_impl(PyObject *module)
6603/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006604{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006605 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006606}
Larry Hastings2f936352014-08-05 14:04:04 +10006607#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006609
Berker Peksag39404992016-09-15 20:45:16 +03006610#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006611/*[clinic input]
6612os.getpid
6613
6614Return the current process id.
6615[clinic start generated code]*/
6616
Larry Hastings2f936352014-08-05 14:04:04 +10006617static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006618os_getpid_impl(PyObject *module)
6619/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006620{
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006622}
Berker Peksag39404992016-09-15 20:45:16 +03006623#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006624
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006625#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006626
6627/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006628PyDoc_STRVAR(posix_getgrouplist__doc__,
6629"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6630Returns a list of groups to which a user belongs.\n\n\
6631 user: username to lookup\n\
6632 group: base group id of the user");
6633
6634static PyObject *
6635posix_getgrouplist(PyObject *self, PyObject *args)
6636{
6637#ifdef NGROUPS_MAX
6638#define MAX_GROUPS NGROUPS_MAX
6639#else
6640 /* defined to be 16 on Solaris7, so this should be a small number */
6641#define MAX_GROUPS 64
6642#endif
6643
6644 const char *user;
6645 int i, ngroups;
6646 PyObject *list;
6647#ifdef __APPLE__
6648 int *groups, basegid;
6649#else
6650 gid_t *groups, basegid;
6651#endif
6652 ngroups = MAX_GROUPS;
6653
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006654#ifdef __APPLE__
6655 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006656 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006657#else
6658 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6659 _Py_Gid_Converter, &basegid))
6660 return NULL;
6661#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006662
6663#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006664 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006665#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006666 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006667#endif
6668 if (groups == NULL)
6669 return PyErr_NoMemory();
6670
6671 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6672 PyMem_Del(groups);
6673 return posix_error();
6674 }
6675
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006676#ifdef _Py_MEMORY_SANITIZER
6677 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6678 __msan_unpoison(&ngroups, sizeof(ngroups));
6679 __msan_unpoison(groups, ngroups*sizeof(*groups));
6680#endif
6681
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006682 list = PyList_New(ngroups);
6683 if (list == NULL) {
6684 PyMem_Del(groups);
6685 return NULL;
6686 }
6687
6688 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006689#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006690 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006691#else
6692 PyObject *o = _PyLong_FromGid(groups[i]);
6693#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006694 if (o == NULL) {
6695 Py_DECREF(list);
6696 PyMem_Del(groups);
6697 return NULL;
6698 }
6699 PyList_SET_ITEM(list, i, o);
6700 }
6701
6702 PyMem_Del(groups);
6703
6704 return list;
6705}
Larry Hastings2f936352014-08-05 14:04:04 +10006706#endif /* HAVE_GETGROUPLIST */
6707
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006708
Fred Drakec9680921999-12-13 16:37:25 +00006709#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006710/*[clinic input]
6711os.getgroups
6712
6713Return list of supplemental group IDs for the process.
6714[clinic start generated code]*/
6715
Larry Hastings2f936352014-08-05 14:04:04 +10006716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006717os_getgroups_impl(PyObject *module)
6718/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006719{
6720 PyObject *result = NULL;
6721
Fred Drakec9680921999-12-13 16:37:25 +00006722#ifdef NGROUPS_MAX
6723#define MAX_GROUPS NGROUPS_MAX
6724#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006726#define MAX_GROUPS 64
6727#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006729
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006730 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006731 * This is a helper variable to store the intermediate result when
6732 * that happens.
6733 *
6734 * To keep the code readable the OSX behaviour is unconditional,
6735 * according to the POSIX spec this should be safe on all unix-y
6736 * systems.
6737 */
6738 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006740
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006741#ifdef __APPLE__
6742 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6743 * there are more groups than can fit in grouplist. Therefore, on OS X
6744 * always first call getgroups with length 0 to get the actual number
6745 * of groups.
6746 */
6747 n = getgroups(0, NULL);
6748 if (n < 0) {
6749 return posix_error();
6750 } else if (n <= MAX_GROUPS) {
6751 /* groups will fit in existing array */
6752 alt_grouplist = grouplist;
6753 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006754 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006755 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006756 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006757 }
6758 }
6759
6760 n = getgroups(n, alt_grouplist);
6761 if (n == -1) {
6762 if (alt_grouplist != grouplist) {
6763 PyMem_Free(alt_grouplist);
6764 }
6765 return posix_error();
6766 }
6767#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006768 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006769 if (n < 0) {
6770 if (errno == EINVAL) {
6771 n = getgroups(0, NULL);
6772 if (n == -1) {
6773 return posix_error();
6774 }
6775 if (n == 0) {
6776 /* Avoid malloc(0) */
6777 alt_grouplist = grouplist;
6778 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006779 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006780 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006781 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006782 }
6783 n = getgroups(n, alt_grouplist);
6784 if (n == -1) {
6785 PyMem_Free(alt_grouplist);
6786 return posix_error();
6787 }
6788 }
6789 } else {
6790 return posix_error();
6791 }
6792 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006793#endif
6794
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006795 result = PyList_New(n);
6796 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 int i;
6798 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006799 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006801 Py_DECREF(result);
6802 result = NULL;
6803 break;
Fred Drakec9680921999-12-13 16:37:25 +00006804 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006806 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006807 }
6808
6809 if (alt_grouplist != grouplist) {
6810 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006812
Fred Drakec9680921999-12-13 16:37:25 +00006813 return result;
6814}
Larry Hastings2f936352014-08-05 14:04:04 +10006815#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006816
Antoine Pitroub7572f02009-12-02 20:46:48 +00006817#ifdef HAVE_INITGROUPS
6818PyDoc_STRVAR(posix_initgroups__doc__,
6819"initgroups(username, gid) -> None\n\n\
6820Call the system initgroups() to initialize the group access list with all of\n\
6821the groups of which the specified username is a member, plus the specified\n\
6822group id.");
6823
Larry Hastings2f936352014-08-05 14:04:04 +10006824/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006825static PyObject *
6826posix_initgroups(PyObject *self, PyObject *args)
6827{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006828 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006829 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006830 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006831#ifdef __APPLE__
6832 int gid;
6833#else
6834 gid_t gid;
6835#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006836
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006837#ifdef __APPLE__
6838 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6839 PyUnicode_FSConverter, &oname,
6840 &gid))
6841#else
6842 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6843 PyUnicode_FSConverter, &oname,
6844 _Py_Gid_Converter, &gid))
6845#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006847 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006848
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006849 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006850 Py_DECREF(oname);
6851 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006853
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006854 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006855}
Larry Hastings2f936352014-08-05 14:04:04 +10006856#endif /* HAVE_INITGROUPS */
6857
Antoine Pitroub7572f02009-12-02 20:46:48 +00006858
Martin v. Löwis606edc12002-06-13 21:09:11 +00006859#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006860/*[clinic input]
6861os.getpgid
6862
6863 pid: pid_t
6864
6865Call the system call getpgid(), and return the result.
6866[clinic start generated code]*/
6867
Larry Hastings2f936352014-08-05 14:04:04 +10006868static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006869os_getpgid_impl(PyObject *module, pid_t pid)
6870/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006871{
6872 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 if (pgid < 0)
6874 return posix_error();
6875 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006876}
6877#endif /* HAVE_GETPGID */
6878
6879
Guido van Rossumb6775db1994-08-01 11:34:53 +00006880#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006881/*[clinic input]
6882os.getpgrp
6883
6884Return the current process group id.
6885[clinic start generated code]*/
6886
Larry Hastings2f936352014-08-05 14:04:04 +10006887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006888os_getpgrp_impl(PyObject *module)
6889/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006890{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006891#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006893#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006894 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006895#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006896}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006897#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006898
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006899
Guido van Rossumb6775db1994-08-01 11:34:53 +00006900#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006901/*[clinic input]
6902os.setpgrp
6903
6904Make the current process the leader of its process group.
6905[clinic start generated code]*/
6906
Larry Hastings2f936352014-08-05 14:04:04 +10006907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006908os_setpgrp_impl(PyObject *module)
6909/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006910{
Guido van Rossum64933891994-10-20 21:56:42 +00006911#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006913#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006915#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006917 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006918}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006919#endif /* HAVE_SETPGRP */
6920
Guido van Rossumad0ee831995-03-01 10:34:45 +00006921#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006922
6923#ifdef MS_WINDOWS
6924#include <tlhelp32.h>
6925
6926static PyObject*
6927win32_getppid()
6928{
6929 HANDLE snapshot;
6930 pid_t mypid;
6931 PyObject* result = NULL;
6932 BOOL have_record;
6933 PROCESSENTRY32 pe;
6934
6935 mypid = getpid(); /* This function never fails */
6936
6937 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6938 if (snapshot == INVALID_HANDLE_VALUE)
6939 return PyErr_SetFromWindowsErr(GetLastError());
6940
6941 pe.dwSize = sizeof(pe);
6942 have_record = Process32First(snapshot, &pe);
6943 while (have_record) {
6944 if (mypid == (pid_t)pe.th32ProcessID) {
6945 /* We could cache the ulong value in a static variable. */
6946 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6947 break;
6948 }
6949
6950 have_record = Process32Next(snapshot, &pe);
6951 }
6952
6953 /* If our loop exits and our pid was not found (result will be NULL)
6954 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6955 * error anyway, so let's raise it. */
6956 if (!result)
6957 result = PyErr_SetFromWindowsErr(GetLastError());
6958
6959 CloseHandle(snapshot);
6960
6961 return result;
6962}
6963#endif /*MS_WINDOWS*/
6964
Larry Hastings2f936352014-08-05 14:04:04 +10006965
6966/*[clinic input]
6967os.getppid
6968
6969Return the parent's process id.
6970
6971If the parent process has already exited, Windows machines will still
6972return its id; others systems will return the id of the 'init' process (1).
6973[clinic start generated code]*/
6974
Larry Hastings2f936352014-08-05 14:04:04 +10006975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006976os_getppid_impl(PyObject *module)
6977/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006978{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006979#ifdef MS_WINDOWS
6980 return win32_getppid();
6981#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006983#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006984}
6985#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006987
Fred Drake12c6e2d1999-12-14 21:25:03 +00006988#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006989/*[clinic input]
6990os.getlogin
6991
6992Return the actual login name.
6993[clinic start generated code]*/
6994
Larry Hastings2f936352014-08-05 14:04:04 +10006995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006996os_getlogin_impl(PyObject *module)
6997/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006998{
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007000#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007001 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007002 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007003
7004 if (GetUserNameW(user_name, &num_chars)) {
7005 /* num_chars is the number of unicode chars plus null terminator */
7006 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007007 }
7008 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007009 result = PyErr_SetFromWindowsErr(GetLastError());
7010#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 char *name;
7012 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007013
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 errno = 0;
7015 name = getlogin();
7016 if (name == NULL) {
7017 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007018 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007019 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007020 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 }
7022 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007023 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007025#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007026 return result;
7027}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007028#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007029
Larry Hastings2f936352014-08-05 14:04:04 +10007030
Guido van Rossumad0ee831995-03-01 10:34:45 +00007031#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007032/*[clinic input]
7033os.getuid
7034
7035Return the current process's user id.
7036[clinic start generated code]*/
7037
Larry Hastings2f936352014-08-05 14:04:04 +10007038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007039os_getuid_impl(PyObject *module)
7040/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007041{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007042 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007043}
Larry Hastings2f936352014-08-05 14:04:04 +10007044#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007046
Brian Curtineb24d742010-04-12 17:16:38 +00007047#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007048#define HAVE_KILL
7049#endif /* MS_WINDOWS */
7050
7051#ifdef HAVE_KILL
7052/*[clinic input]
7053os.kill
7054
7055 pid: pid_t
7056 signal: Py_ssize_t
7057 /
7058
7059Kill a process with a signal.
7060[clinic start generated code]*/
7061
Larry Hastings2f936352014-08-05 14:04:04 +10007062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007063os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7064/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007065#ifndef MS_WINDOWS
7066{
7067 if (kill(pid, (int)signal) == -1)
7068 return posix_error();
7069 Py_RETURN_NONE;
7070}
7071#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007072{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007073 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007074 DWORD sig = (DWORD)signal;
7075 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007077
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 /* Console processes which share a common console can be sent CTRL+C or
7079 CTRL+BREAK events, provided they handle said events. */
7080 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007081 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 err = GetLastError();
7083 PyErr_SetFromWindowsErr(err);
7084 }
7085 else
7086 Py_RETURN_NONE;
7087 }
Brian Curtineb24d742010-04-12 17:16:38 +00007088
Victor Stinner8c62be82010-05-06 00:08:46 +00007089 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7090 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007091 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007092 if (handle == NULL) {
7093 err = GetLastError();
7094 return PyErr_SetFromWindowsErr(err);
7095 }
Brian Curtineb24d742010-04-12 17:16:38 +00007096
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 if (TerminateProcess(handle, sig) == 0) {
7098 err = GetLastError();
7099 result = PyErr_SetFromWindowsErr(err);
7100 } else {
7101 Py_INCREF(Py_None);
7102 result = Py_None;
7103 }
Brian Curtineb24d742010-04-12 17:16:38 +00007104
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 CloseHandle(handle);
7106 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007107}
Larry Hastings2f936352014-08-05 14:04:04 +10007108#endif /* !MS_WINDOWS */
7109#endif /* HAVE_KILL */
7110
7111
7112#ifdef HAVE_KILLPG
7113/*[clinic input]
7114os.killpg
7115
7116 pgid: pid_t
7117 signal: int
7118 /
7119
7120Kill a process group with a signal.
7121[clinic start generated code]*/
7122
Larry Hastings2f936352014-08-05 14:04:04 +10007123static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007124os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7125/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007126{
7127 /* XXX some man pages make the `pgid` parameter an int, others
7128 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7129 take the same type. Moreover, pid_t is always at least as wide as
7130 int (else compilation of this module fails), which is safe. */
7131 if (killpg(pgid, signal) == -1)
7132 return posix_error();
7133 Py_RETURN_NONE;
7134}
7135#endif /* HAVE_KILLPG */
7136
Brian Curtineb24d742010-04-12 17:16:38 +00007137
Guido van Rossumc0125471996-06-28 18:55:32 +00007138#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007139#ifdef HAVE_SYS_LOCK_H
7140#include <sys/lock.h>
7141#endif
7142
Larry Hastings2f936352014-08-05 14:04:04 +10007143/*[clinic input]
7144os.plock
7145 op: int
7146 /
7147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007148Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007149[clinic start generated code]*/
7150
Larry Hastings2f936352014-08-05 14:04:04 +10007151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007152os_plock_impl(PyObject *module, int op)
7153/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007154{
Victor Stinner8c62be82010-05-06 00:08:46 +00007155 if (plock(op) == -1)
7156 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007157 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007158}
Larry Hastings2f936352014-08-05 14:04:04 +10007159#endif /* HAVE_PLOCK */
7160
Guido van Rossumc0125471996-06-28 18:55:32 +00007161
Guido van Rossumb6775db1994-08-01 11:34:53 +00007162#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007163/*[clinic input]
7164os.setuid
7165
7166 uid: uid_t
7167 /
7168
7169Set the current process's user id.
7170[clinic start generated code]*/
7171
Larry Hastings2f936352014-08-05 14:04:04 +10007172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007173os_setuid_impl(PyObject *module, uid_t uid)
7174/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007175{
Victor Stinner8c62be82010-05-06 00:08:46 +00007176 if (setuid(uid) < 0)
7177 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007178 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007179}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007180#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007182
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007183#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007184/*[clinic input]
7185os.seteuid
7186
7187 euid: uid_t
7188 /
7189
7190Set the current process's effective user id.
7191[clinic start generated code]*/
7192
Larry Hastings2f936352014-08-05 14:04:04 +10007193static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007194os_seteuid_impl(PyObject *module, uid_t euid)
7195/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007196{
7197 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007199 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007200}
7201#endif /* HAVE_SETEUID */
7202
Larry Hastings2f936352014-08-05 14:04:04 +10007203
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007204#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007205/*[clinic input]
7206os.setegid
7207
7208 egid: gid_t
7209 /
7210
7211Set the current process's effective group id.
7212[clinic start generated code]*/
7213
Larry Hastings2f936352014-08-05 14:04:04 +10007214static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007215os_setegid_impl(PyObject *module, gid_t egid)
7216/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007217{
7218 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007220 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007221}
7222#endif /* HAVE_SETEGID */
7223
Larry Hastings2f936352014-08-05 14:04:04 +10007224
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007225#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007226/*[clinic input]
7227os.setreuid
7228
7229 ruid: uid_t
7230 euid: uid_t
7231 /
7232
7233Set the current process's real and effective user ids.
7234[clinic start generated code]*/
7235
Larry Hastings2f936352014-08-05 14:04:04 +10007236static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007237os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7238/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007239{
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 if (setreuid(ruid, euid) < 0) {
7241 return posix_error();
7242 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007243 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007244 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007245}
7246#endif /* HAVE_SETREUID */
7247
Larry Hastings2f936352014-08-05 14:04:04 +10007248
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007249#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007250/*[clinic input]
7251os.setregid
7252
7253 rgid: gid_t
7254 egid: gid_t
7255 /
7256
7257Set the current process's real and effective group ids.
7258[clinic start generated code]*/
7259
Larry Hastings2f936352014-08-05 14:04:04 +10007260static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007261os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7262/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007263{
7264 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007265 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007266 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007267}
7268#endif /* HAVE_SETREGID */
7269
Larry Hastings2f936352014-08-05 14:04:04 +10007270
Guido van Rossumb6775db1994-08-01 11:34:53 +00007271#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007272/*[clinic input]
7273os.setgid
7274 gid: gid_t
7275 /
7276
7277Set the current process's group id.
7278[clinic start generated code]*/
7279
Larry Hastings2f936352014-08-05 14:04:04 +10007280static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007281os_setgid_impl(PyObject *module, gid_t gid)
7282/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007283{
Victor Stinner8c62be82010-05-06 00:08:46 +00007284 if (setgid(gid) < 0)
7285 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007286 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007287}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007288#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007289
Larry Hastings2f936352014-08-05 14:04:04 +10007290
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007291#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007292/*[clinic input]
7293os.setgroups
7294
7295 groups: object
7296 /
7297
7298Set the groups of the current process to list.
7299[clinic start generated code]*/
7300
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007301static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007302os_setgroups(PyObject *module, PyObject *groups)
7303/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007304{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007305 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007306 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007307
Victor Stinner8c62be82010-05-06 00:08:46 +00007308 if (!PySequence_Check(groups)) {
7309 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7310 return NULL;
7311 }
7312 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007313 if (len < 0) {
7314 return NULL;
7315 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007316 if (len > MAX_GROUPS) {
7317 PyErr_SetString(PyExc_ValueError, "too many groups");
7318 return NULL;
7319 }
7320 for(i = 0; i < len; i++) {
7321 PyObject *elem;
7322 elem = PySequence_GetItem(groups, i);
7323 if (!elem)
7324 return NULL;
7325 if (!PyLong_Check(elem)) {
7326 PyErr_SetString(PyExc_TypeError,
7327 "groups must be integers");
7328 Py_DECREF(elem);
7329 return NULL;
7330 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007331 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007332 Py_DECREF(elem);
7333 return NULL;
7334 }
7335 }
7336 Py_DECREF(elem);
7337 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007338
Victor Stinner8c62be82010-05-06 00:08:46 +00007339 if (setgroups(len, grouplist) < 0)
7340 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007341 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007342}
7343#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007344
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007345#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7346static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007347wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007348{
Victor Stinner8c62be82010-05-06 00:08:46 +00007349 PyObject *result;
7350 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007351 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007352
Victor Stinner8c62be82010-05-06 00:08:46 +00007353 if (pid == -1)
7354 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007355
Victor Stinner8c62be82010-05-06 00:08:46 +00007356 if (struct_rusage == NULL) {
7357 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7358 if (m == NULL)
7359 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007360 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007361 Py_DECREF(m);
7362 if (struct_rusage == NULL)
7363 return NULL;
7364 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007365
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7367 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7368 if (!result)
7369 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007370
7371#ifndef doubletime
7372#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7373#endif
7374
Victor Stinner8c62be82010-05-06 00:08:46 +00007375 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007376 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007377 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007378 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007379#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007380 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7381 SET_INT(result, 2, ru->ru_maxrss);
7382 SET_INT(result, 3, ru->ru_ixrss);
7383 SET_INT(result, 4, ru->ru_idrss);
7384 SET_INT(result, 5, ru->ru_isrss);
7385 SET_INT(result, 6, ru->ru_minflt);
7386 SET_INT(result, 7, ru->ru_majflt);
7387 SET_INT(result, 8, ru->ru_nswap);
7388 SET_INT(result, 9, ru->ru_inblock);
7389 SET_INT(result, 10, ru->ru_oublock);
7390 SET_INT(result, 11, ru->ru_msgsnd);
7391 SET_INT(result, 12, ru->ru_msgrcv);
7392 SET_INT(result, 13, ru->ru_nsignals);
7393 SET_INT(result, 14, ru->ru_nvcsw);
7394 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007395#undef SET_INT
7396
Victor Stinner8c62be82010-05-06 00:08:46 +00007397 if (PyErr_Occurred()) {
7398 Py_DECREF(result);
7399 return NULL;
7400 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007401
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007403}
7404#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7405
Larry Hastings2f936352014-08-05 14:04:04 +10007406
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007407#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007408/*[clinic input]
7409os.wait3
7410
7411 options: int
7412Wait for completion of a child process.
7413
7414Returns a tuple of information about the child process:
7415 (pid, status, rusage)
7416[clinic start generated code]*/
7417
Larry Hastings2f936352014-08-05 14:04:04 +10007418static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007419os_wait3_impl(PyObject *module, int options)
7420/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007421{
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007423 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007424 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007425 WAIT_TYPE status;
7426 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007427
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007428 do {
7429 Py_BEGIN_ALLOW_THREADS
7430 pid = wait3(&status, options, &ru);
7431 Py_END_ALLOW_THREADS
7432 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7433 if (pid < 0)
7434 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007435
Victor Stinner4195b5c2012-02-08 23:03:19 +01007436 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007437}
7438#endif /* HAVE_WAIT3 */
7439
Larry Hastings2f936352014-08-05 14:04:04 +10007440
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007441#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007442/*[clinic input]
7443
7444os.wait4
7445
7446 pid: pid_t
7447 options: int
7448
7449Wait for completion of a specific child process.
7450
7451Returns a tuple of information about the child process:
7452 (pid, status, rusage)
7453[clinic start generated code]*/
7454
Larry Hastings2f936352014-08-05 14:04:04 +10007455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007456os_wait4_impl(PyObject *module, pid_t pid, int options)
7457/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007458{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007459 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007460 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007461 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 WAIT_TYPE status;
7463 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007464
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007465 do {
7466 Py_BEGIN_ALLOW_THREADS
7467 res = wait4(pid, &status, options, &ru);
7468 Py_END_ALLOW_THREADS
7469 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7470 if (res < 0)
7471 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007472
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007473 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007474}
7475#endif /* HAVE_WAIT4 */
7476
Larry Hastings2f936352014-08-05 14:04:04 +10007477
Ross Lagerwall7807c352011-03-17 20:20:30 +02007478#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007479/*[clinic input]
7480os.waitid
7481
7482 idtype: idtype_t
7483 Must be one of be P_PID, P_PGID or P_ALL.
7484 id: id_t
7485 The id to wait on.
7486 options: int
7487 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7488 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7489 /
7490
7491Returns the result of waiting for a process or processes.
7492
7493Returns either waitid_result or None if WNOHANG is specified and there are
7494no children in a waitable state.
7495[clinic start generated code]*/
7496
Larry Hastings2f936352014-08-05 14:04:04 +10007497static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007498os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7499/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007500{
7501 PyObject *result;
7502 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007503 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007504 siginfo_t si;
7505 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007506
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007507 do {
7508 Py_BEGIN_ALLOW_THREADS
7509 res = waitid(idtype, id, &si, options);
7510 Py_END_ALLOW_THREADS
7511 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7512 if (res < 0)
7513 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007514
7515 if (si.si_pid == 0)
7516 Py_RETURN_NONE;
7517
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007518 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007519 if (!result)
7520 return NULL;
7521
7522 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007523 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007524 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7525 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7526 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7527 if (PyErr_Occurred()) {
7528 Py_DECREF(result);
7529 return NULL;
7530 }
7531
7532 return result;
7533}
Larry Hastings2f936352014-08-05 14:04:04 +10007534#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007535
Larry Hastings2f936352014-08-05 14:04:04 +10007536
7537#if defined(HAVE_WAITPID)
7538/*[clinic input]
7539os.waitpid
7540 pid: pid_t
7541 options: int
7542 /
7543
7544Wait for completion of a given child process.
7545
7546Returns a tuple of information regarding the child process:
7547 (pid, status)
7548
7549The options argument is ignored on Windows.
7550[clinic start generated code]*/
7551
Larry Hastings2f936352014-08-05 14:04:04 +10007552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007553os_waitpid_impl(PyObject *module, pid_t pid, int options)
7554/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007555{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007556 pid_t res;
7557 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007558 WAIT_TYPE status;
7559 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007560
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007561 do {
7562 Py_BEGIN_ALLOW_THREADS
7563 res = waitpid(pid, &status, options);
7564 Py_END_ALLOW_THREADS
7565 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7566 if (res < 0)
7567 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007568
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007569 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007570}
Tim Petersab034fa2002-02-01 11:27:43 +00007571#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007572/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007573/*[clinic input]
7574os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007575 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007576 options: int
7577 /
7578
7579Wait for completion of a given process.
7580
7581Returns a tuple of information regarding the process:
7582 (pid, status << 8)
7583
7584The options argument is ignored on Windows.
7585[clinic start generated code]*/
7586
Larry Hastings2f936352014-08-05 14:04:04 +10007587static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007588os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007589/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007590{
7591 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007592 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007593 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007594
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007595 do {
7596 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007597 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007598 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007599 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007600 Py_END_ALLOW_THREADS
7601 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007602 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007603 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007604
Victor Stinner8c62be82010-05-06 00:08:46 +00007605 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007606 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007607}
Larry Hastings2f936352014-08-05 14:04:04 +10007608#endif
7609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Guido van Rossumad0ee831995-03-01 10:34:45 +00007611#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007612/*[clinic input]
7613os.wait
7614
7615Wait for completion of a child process.
7616
7617Returns a tuple of information about the child process:
7618 (pid, status)
7619[clinic start generated code]*/
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007622os_wait_impl(PyObject *module)
7623/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007624{
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007626 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 WAIT_TYPE status;
7628 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007629
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007630 do {
7631 Py_BEGIN_ALLOW_THREADS
7632 pid = wait(&status);
7633 Py_END_ALLOW_THREADS
7634 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7635 if (pid < 0)
7636 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007637
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007639}
Larry Hastings2f936352014-08-05 14:04:04 +10007640#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007641
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007642
Larry Hastings9cf065c2012-06-22 16:30:09 -07007643#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007644/*[clinic input]
7645os.readlink
7646
7647 path: path_t
7648 *
7649 dir_fd: dir_fd(requires='readlinkat') = None
7650
7651Return a string representing the path to which the symbolic link points.
7652
7653If dir_fd is not None, it should be a file descriptor open to a directory,
7654and path should be relative; path will then be relative to that directory.
7655
7656dir_fd may not be implemented on your platform. If it is unavailable,
7657using it will raise a NotImplementedError.
7658[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007659
Barry Warsaw53699e91996-12-10 23:23:01 +00007660static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007661os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7662/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007663{
Berker Peksage0b5b202018-08-15 13:03:41 +03007664#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007665 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007666 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007667
7668 Py_BEGIN_ALLOW_THREADS
7669#ifdef HAVE_READLINKAT
7670 if (dir_fd != DEFAULT_DIR_FD)
7671 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7672 else
7673#endif
7674 length = readlink(path->narrow, buffer, MAXPATHLEN);
7675 Py_END_ALLOW_THREADS
7676
7677 if (length < 0) {
7678 return path_error(path);
7679 }
7680 buffer[length] = '\0';
7681
7682 if (PyUnicode_Check(path->object))
7683 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7684 else
7685 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007686#elif defined(MS_WINDOWS)
7687 DWORD n_bytes_returned;
7688 DWORD io_result;
7689 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007690 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7691 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7692 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007693 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007694
Larry Hastings2f936352014-08-05 14:04:04 +10007695 /* First get a handle to the reparse point */
7696 Py_BEGIN_ALLOW_THREADS
7697 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007698 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007699 0,
7700 0,
7701 0,
7702 OPEN_EXISTING,
7703 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7704 0);
7705 Py_END_ALLOW_THREADS
7706
Berker Peksage0b5b202018-08-15 13:03:41 +03007707 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007708 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007709 }
Larry Hastings2f936352014-08-05 14:04:04 +10007710
7711 Py_BEGIN_ALLOW_THREADS
7712 /* New call DeviceIoControl to read the reparse point */
7713 io_result = DeviceIoControl(
7714 reparse_point_handle,
7715 FSCTL_GET_REPARSE_POINT,
7716 0, 0, /* in buffer */
7717 target_buffer, sizeof(target_buffer),
7718 &n_bytes_returned,
7719 0 /* we're not using OVERLAPPED_IO */
7720 );
7721 CloseHandle(reparse_point_handle);
7722 Py_END_ALLOW_THREADS
7723
Berker Peksage0b5b202018-08-15 13:03:41 +03007724 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007725 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007726 }
Larry Hastings2f936352014-08-05 14:04:04 +10007727
7728 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7729 {
7730 PyErr_SetString(PyExc_ValueError,
7731 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007732 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007733 }
SSE43c34aad2018-02-13 00:10:35 +07007734 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7735 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007736
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007737 result = PyUnicode_FromWideChar(print_name,
7738 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7739 if (path->narrow) {
7740 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007741 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007742 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007743#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007744}
Berker Peksage0b5b202018-08-15 13:03:41 +03007745#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007746
Larry Hastings9cf065c2012-06-22 16:30:09 -07007747#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007748
7749#if defined(MS_WINDOWS)
7750
7751/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Steve Dower6921e732018-03-05 14:26:08 -08007752static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007753
Larry Hastings9cf065c2012-06-22 16:30:09 -07007754static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007755check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007756{
7757 HINSTANCE hKernel32;
7758 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007759 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007760 return 1;
Tony Roberts4860f012019-02-02 18:16:42 +01007761
7762 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007763 hKernel32 = GetModuleHandleW(L"KERNEL32");
7764 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7765 "CreateSymbolicLinkW");
Tony Roberts4860f012019-02-02 18:16:42 +01007766 Py_END_ALLOW_THREADS
7767
Steve Dowercc16be82016-09-08 10:35:16 -07007768 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007769}
7770
Steve Dower6921e732018-03-05 14:26:08 -08007771/* Remove the last portion of the path - return 0 on success */
7772static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007773_dirnameW(WCHAR *path)
7774{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007775 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007776 size_t length = wcsnlen_s(path, MAX_PATH);
7777 if (length == MAX_PATH) {
7778 return -1;
7779 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007780
7781 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007782 for(ptr = path + length; ptr != path; ptr--) {
7783 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007784 break;
Steve Dower6921e732018-03-05 14:26:08 -08007785 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007786 }
7787 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007788 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007789}
7790
Victor Stinner31b3b922013-06-05 01:49:17 +02007791/* Is this path absolute? */
7792static int
7793_is_absW(const WCHAR *path)
7794{
Steve Dower6921e732018-03-05 14:26:08 -08007795 return path[0] == L'\\' || path[0] == L'/' ||
7796 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007797}
7798
Steve Dower6921e732018-03-05 14:26:08 -08007799/* join root and rest with a backslash - return 0 on success */
7800static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007801_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7802{
Victor Stinner31b3b922013-06-05 01:49:17 +02007803 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007804 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007805 }
7806
Steve Dower6921e732018-03-05 14:26:08 -08007807 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7808 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007809 }
Steve Dower6921e732018-03-05 14:26:08 -08007810
7811 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7812 return -1;
7813 }
7814
7815 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007816}
7817
Victor Stinner31b3b922013-06-05 01:49:17 +02007818/* Return True if the path at src relative to dest is a directory */
7819static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007820_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007821{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007822 WIN32_FILE_ATTRIBUTE_DATA src_info;
7823 WCHAR dest_parent[MAX_PATH];
7824 WCHAR src_resolved[MAX_PATH] = L"";
7825
7826 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007827 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7828 _dirnameW(dest_parent)) {
7829 return 0;
7830 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007831 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007832 if (_joinW(src_resolved, dest_parent, src)) {
7833 return 0;
7834 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007835 return (
7836 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7837 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7838 );
7839}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007840#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007841
Larry Hastings2f936352014-08-05 14:04:04 +10007842
7843/*[clinic input]
7844os.symlink
7845 src: path_t
7846 dst: path_t
7847 target_is_directory: bool = False
7848 *
7849 dir_fd: dir_fd(requires='symlinkat')=None
7850
7851# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7852
7853Create a symbolic link pointing to src named dst.
7854
7855target_is_directory is required on Windows if the target is to be
7856 interpreted as a directory. (On Windows, symlink requires
7857 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7858 target_is_directory is ignored on non-Windows platforms.
7859
7860If dir_fd is not None, it should be a file descriptor open to a directory,
7861 and path should be relative; path will then be relative to that directory.
7862dir_fd may not be implemented on your platform.
7863 If it is unavailable, using it will raise a NotImplementedError.
7864
7865[clinic start generated code]*/
7866
Larry Hastings2f936352014-08-05 14:04:04 +10007867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007868os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007869 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007870/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007871{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007872#ifdef MS_WINDOWS
7873 DWORD result;
7874#else
7875 int result;
7876#endif
7877
Larry Hastings9cf065c2012-06-22 16:30:09 -07007878#ifdef MS_WINDOWS
7879 if (!check_CreateSymbolicLink()) {
7880 PyErr_SetString(PyExc_NotImplementedError,
7881 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007882 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007883 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007884 if (!win32_can_symlink) {
7885 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007886 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007887 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007888#endif
7889
Larry Hastings9cf065c2012-06-22 16:30:09 -07007890#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007891
Larry Hastings9cf065c2012-06-22 16:30:09 -07007892 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007893 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007894 /* if src is a directory, ensure target_is_directory==1 */
7895 target_is_directory |= _check_dirW(src->wide, dst->wide);
7896 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7897 target_is_directory);
Steve Dower6921e732018-03-05 14:26:08 -08007898 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007899 Py_END_ALLOW_THREADS
7900
Larry Hastings2f936352014-08-05 14:04:04 +10007901 if (!result)
7902 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007903
7904#else
7905
Steve Dower6921e732018-03-05 14:26:08 -08007906 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7907 PyErr_SetString(PyExc_ValueError,
7908 "symlink: src and dst must be the same type");
7909 return NULL;
7910 }
7911
Larry Hastings9cf065c2012-06-22 16:30:09 -07007912 Py_BEGIN_ALLOW_THREADS
7913#if HAVE_SYMLINKAT
7914 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007915 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007916 else
7917#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007918 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007919 Py_END_ALLOW_THREADS
7920
Larry Hastings2f936352014-08-05 14:04:04 +10007921 if (result)
7922 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007923#endif
7924
Larry Hastings2f936352014-08-05 14:04:04 +10007925 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007926}
7927#endif /* HAVE_SYMLINK */
7928
Larry Hastings9cf065c2012-06-22 16:30:09 -07007929
Brian Curtind40e6f72010-07-08 21:39:08 +00007930
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007931
Larry Hastings605a62d2012-06-24 04:33:36 -07007932static PyStructSequence_Field times_result_fields[] = {
7933 {"user", "user time"},
7934 {"system", "system time"},
7935 {"children_user", "user time of children"},
7936 {"children_system", "system time of children"},
7937 {"elapsed", "elapsed time since an arbitrary point in the past"},
7938 {NULL}
7939};
7940
7941PyDoc_STRVAR(times_result__doc__,
7942"times_result: Result from os.times().\n\n\
7943This object may be accessed either as a tuple of\n\
7944 (user, system, children_user, children_system, elapsed),\n\
7945or via the attributes user, system, children_user, children_system,\n\
7946and elapsed.\n\
7947\n\
7948See os.times for more information.");
7949
7950static PyStructSequence_Desc times_result_desc = {
7951 "times_result", /* name */
7952 times_result__doc__, /* doc */
7953 times_result_fields,
7954 5
7955};
7956
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007957static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07007958
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007959#ifdef MS_WINDOWS
7960#define HAVE_TIMES /* mandatory, for the method table */
7961#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007962
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007963#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007964
7965static PyObject *
7966build_times_result(double user, double system,
7967 double children_user, double children_system,
7968 double elapsed)
7969{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007970 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07007971 if (value == NULL)
7972 return NULL;
7973
7974#define SET(i, field) \
7975 { \
7976 PyObject *o = PyFloat_FromDouble(field); \
7977 if (!o) { \
7978 Py_DECREF(value); \
7979 return NULL; \
7980 } \
7981 PyStructSequence_SET_ITEM(value, i, o); \
7982 } \
7983
7984 SET(0, user);
7985 SET(1, system);
7986 SET(2, children_user);
7987 SET(3, children_system);
7988 SET(4, elapsed);
7989
7990#undef SET
7991
7992 return value;
7993}
7994
Larry Hastings605a62d2012-06-24 04:33:36 -07007995
Larry Hastings2f936352014-08-05 14:04:04 +10007996#ifndef MS_WINDOWS
7997#define NEED_TICKS_PER_SECOND
7998static long ticks_per_second = -1;
7999#endif /* MS_WINDOWS */
8000
8001/*[clinic input]
8002os.times
8003
8004Return a collection containing process timing information.
8005
8006The object returned behaves like a named tuple with these fields:
8007 (utime, stime, cutime, cstime, elapsed_time)
8008All fields are floating point numbers.
8009[clinic start generated code]*/
8010
Larry Hastings2f936352014-08-05 14:04:04 +10008011static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008012os_times_impl(PyObject *module)
8013/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008014#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008015{
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 FILETIME create, exit, kernel, user;
8017 HANDLE hProc;
8018 hProc = GetCurrentProcess();
8019 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8020 /* The fields of a FILETIME structure are the hi and lo part
8021 of a 64-bit value expressed in 100 nanosecond units.
8022 1e7 is one second in such units; 1e-7 the inverse.
8023 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8024 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008025 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 (double)(user.dwHighDateTime*429.4967296 +
8027 user.dwLowDateTime*1e-7),
8028 (double)(kernel.dwHighDateTime*429.4967296 +
8029 kernel.dwLowDateTime*1e-7),
8030 (double)0,
8031 (double)0,
8032 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008033}
Larry Hastings2f936352014-08-05 14:04:04 +10008034#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008035{
Larry Hastings2f936352014-08-05 14:04:04 +10008036
8037
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008038 struct tms t;
8039 clock_t c;
8040 errno = 0;
8041 c = times(&t);
8042 if (c == (clock_t) -1)
8043 return posix_error();
8044 return build_times_result(
8045 (double)t.tms_utime / ticks_per_second,
8046 (double)t.tms_stime / ticks_per_second,
8047 (double)t.tms_cutime / ticks_per_second,
8048 (double)t.tms_cstime / ticks_per_second,
8049 (double)c / ticks_per_second);
8050}
Larry Hastings2f936352014-08-05 14:04:04 +10008051#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008052#endif /* HAVE_TIMES */
8053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008054
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008055#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008056/*[clinic input]
8057os.getsid
8058
8059 pid: pid_t
8060 /
8061
8062Call the system call getsid(pid) and return the result.
8063[clinic start generated code]*/
8064
Larry Hastings2f936352014-08-05 14:04:04 +10008065static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008066os_getsid_impl(PyObject *module, pid_t pid)
8067/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008068{
Victor Stinner8c62be82010-05-06 00:08:46 +00008069 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008070 sid = getsid(pid);
8071 if (sid < 0)
8072 return posix_error();
8073 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008074}
8075#endif /* HAVE_GETSID */
8076
8077
Guido van Rossumb6775db1994-08-01 11:34:53 +00008078#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008079/*[clinic input]
8080os.setsid
8081
8082Call the system call setsid().
8083[clinic start generated code]*/
8084
Larry Hastings2f936352014-08-05 14:04:04 +10008085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008086os_setsid_impl(PyObject *module)
8087/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008088{
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 if (setsid() < 0)
8090 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008091 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008092}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008093#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008094
Larry Hastings2f936352014-08-05 14:04:04 +10008095
Guido van Rossumb6775db1994-08-01 11:34:53 +00008096#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008097/*[clinic input]
8098os.setpgid
8099
8100 pid: pid_t
8101 pgrp: pid_t
8102 /
8103
8104Call the system call setpgid(pid, pgrp).
8105[clinic start generated code]*/
8106
Larry Hastings2f936352014-08-05 14:04:04 +10008107static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008108os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8109/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008110{
Victor Stinner8c62be82010-05-06 00:08:46 +00008111 if (setpgid(pid, pgrp) < 0)
8112 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008113 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008114}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008115#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008116
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008117
Guido van Rossumb6775db1994-08-01 11:34:53 +00008118#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008119/*[clinic input]
8120os.tcgetpgrp
8121
8122 fd: int
8123 /
8124
8125Return the process group associated with the terminal specified by fd.
8126[clinic start generated code]*/
8127
Larry Hastings2f936352014-08-05 14:04:04 +10008128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008129os_tcgetpgrp_impl(PyObject *module, int fd)
8130/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008131{
8132 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 if (pgid < 0)
8134 return posix_error();
8135 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008136}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008137#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008139
Guido van Rossumb6775db1994-08-01 11:34:53 +00008140#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008141/*[clinic input]
8142os.tcsetpgrp
8143
8144 fd: int
8145 pgid: pid_t
8146 /
8147
8148Set the process group associated with the terminal specified by fd.
8149[clinic start generated code]*/
8150
Larry Hastings2f936352014-08-05 14:04:04 +10008151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008152os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8153/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008154{
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 if (tcsetpgrp(fd, pgid) < 0)
8156 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008157 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008158}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008159#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008160
Guido van Rossum687dd131993-05-17 08:34:16 +00008161/* Functions acting on file descriptors */
8162
Victor Stinnerdaf45552013-08-28 00:53:59 +02008163#ifdef O_CLOEXEC
8164extern int _Py_open_cloexec_works;
8165#endif
8166
Larry Hastings2f936352014-08-05 14:04:04 +10008167
8168/*[clinic input]
8169os.open -> int
8170 path: path_t
8171 flags: int
8172 mode: int = 0o777
8173 *
8174 dir_fd: dir_fd(requires='openat') = None
8175
8176# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8177
8178Open a file for low level IO. Returns a file descriptor (integer).
8179
8180If dir_fd is not None, it should be a file descriptor open to a directory,
8181 and path should be relative; path will then be relative to that directory.
8182dir_fd may not be implemented on your platform.
8183 If it is unavailable, using it will raise a NotImplementedError.
8184[clinic start generated code]*/
8185
Larry Hastings2f936352014-08-05 14:04:04 +10008186static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008187os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8188/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008189{
8190 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008191 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008192
Victor Stinnerdaf45552013-08-28 00:53:59 +02008193#ifdef O_CLOEXEC
8194 int *atomic_flag_works = &_Py_open_cloexec_works;
8195#elif !defined(MS_WINDOWS)
8196 int *atomic_flag_works = NULL;
8197#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008198
Victor Stinnerdaf45552013-08-28 00:53:59 +02008199#ifdef MS_WINDOWS
8200 flags |= O_NOINHERIT;
8201#elif defined(O_CLOEXEC)
8202 flags |= O_CLOEXEC;
8203#endif
8204
Steve Dower8fc89802015-04-12 00:26:27 -04008205 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008206 do {
8207 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008208#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008209 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008210#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008211#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008212 if (dir_fd != DEFAULT_DIR_FD)
8213 fd = openat(dir_fd, path->narrow, flags, mode);
8214 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008215#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008216 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008217#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008218 Py_END_ALLOW_THREADS
8219 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008220 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008221
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008222 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008223 if (!async_err)
8224 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008225 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008226 }
8227
Victor Stinnerdaf45552013-08-28 00:53:59 +02008228#ifndef MS_WINDOWS
8229 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8230 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008231 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008232 }
8233#endif
8234
Larry Hastings2f936352014-08-05 14:04:04 +10008235 return fd;
8236}
8237
8238
8239/*[clinic input]
8240os.close
8241
8242 fd: int
8243
8244Close a file descriptor.
8245[clinic start generated code]*/
8246
Barry Warsaw53699e91996-12-10 23:23:01 +00008247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008248os_close_impl(PyObject *module, int fd)
8249/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008250{
Larry Hastings2f936352014-08-05 14:04:04 +10008251 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008252 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8253 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8254 * for more details.
8255 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008257 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008259 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 Py_END_ALLOW_THREADS
8261 if (res < 0)
8262 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008263 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008264}
8265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008266
Larry Hastings2f936352014-08-05 14:04:04 +10008267/*[clinic input]
8268os.closerange
8269
8270 fd_low: int
8271 fd_high: int
8272 /
8273
8274Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8275[clinic start generated code]*/
8276
Larry Hastings2f936352014-08-05 14:04:04 +10008277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008278os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8279/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008280{
8281 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008282 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008283 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008284 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008285 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008286 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 Py_END_ALLOW_THREADS
8288 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008289}
8290
8291
Larry Hastings2f936352014-08-05 14:04:04 +10008292/*[clinic input]
8293os.dup -> int
8294
8295 fd: int
8296 /
8297
8298Return a duplicate of a file descriptor.
8299[clinic start generated code]*/
8300
Larry Hastings2f936352014-08-05 14:04:04 +10008301static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008302os_dup_impl(PyObject *module, int fd)
8303/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008304{
8305 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008306}
8307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008308
Larry Hastings2f936352014-08-05 14:04:04 +10008309/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008310os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008311 fd: int
8312 fd2: int
8313 inheritable: bool=True
8314
8315Duplicate file descriptor.
8316[clinic start generated code]*/
8317
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008318static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008319os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008320/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008321{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008322 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008323#if defined(HAVE_DUP3) && \
8324 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8325 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008326 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008327#endif
8328
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008329 if (fd < 0 || fd2 < 0) {
8330 posix_error();
8331 return -1;
8332 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008333
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008334 /* dup2() can fail with EINTR if the target FD is already open, because it
8335 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8336 * upon close(), and therefore below.
8337 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008338#ifdef MS_WINDOWS
8339 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008340 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008341 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008342 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008343 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008344 if (res < 0) {
8345 posix_error();
8346 return -1;
8347 }
8348 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008349
8350 /* Character files like console cannot be make non-inheritable */
8351 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8352 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008353 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008354 }
8355
8356#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8357 Py_BEGIN_ALLOW_THREADS
8358 if (!inheritable)
8359 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8360 else
8361 res = dup2(fd, fd2);
8362 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008363 if (res < 0) {
8364 posix_error();
8365 return -1;
8366 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008367
8368#else
8369
8370#ifdef HAVE_DUP3
8371 if (!inheritable && dup3_works != 0) {
8372 Py_BEGIN_ALLOW_THREADS
8373 res = dup3(fd, fd2, O_CLOEXEC);
8374 Py_END_ALLOW_THREADS
8375 if (res < 0) {
8376 if (dup3_works == -1)
8377 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008378 if (dup3_works) {
8379 posix_error();
8380 return -1;
8381 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008382 }
8383 }
8384
8385 if (inheritable || dup3_works == 0)
8386 {
8387#endif
8388 Py_BEGIN_ALLOW_THREADS
8389 res = dup2(fd, fd2);
8390 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008391 if (res < 0) {
8392 posix_error();
8393 return -1;
8394 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008395
8396 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8397 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008398 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008399 }
8400#ifdef HAVE_DUP3
8401 }
8402#endif
8403
8404#endif
8405
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008406 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008407}
8408
Larry Hastings2f936352014-08-05 14:04:04 +10008409
Ross Lagerwall7807c352011-03-17 20:20:30 +02008410#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008411/*[clinic input]
8412os.lockf
8413
8414 fd: int
8415 An open file descriptor.
8416 command: int
8417 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8418 length: Py_off_t
8419 The number of bytes to lock, starting at the current position.
8420 /
8421
8422Apply, test or remove a POSIX lock on an open file descriptor.
8423
8424[clinic start generated code]*/
8425
Larry Hastings2f936352014-08-05 14:04:04 +10008426static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008427os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8428/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008429{
8430 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008431
8432 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008433 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008434 Py_END_ALLOW_THREADS
8435
8436 if (res < 0)
8437 return posix_error();
8438
8439 Py_RETURN_NONE;
8440}
Larry Hastings2f936352014-08-05 14:04:04 +10008441#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008442
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008443
Larry Hastings2f936352014-08-05 14:04:04 +10008444/*[clinic input]
8445os.lseek -> Py_off_t
8446
8447 fd: int
8448 position: Py_off_t
8449 how: int
8450 /
8451
8452Set the position of a file descriptor. Return the new position.
8453
8454Return the new cursor position in number of bytes
8455relative to the beginning of the file.
8456[clinic start generated code]*/
8457
Larry Hastings2f936352014-08-05 14:04:04 +10008458static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008459os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8460/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008461{
8462 Py_off_t result;
8463
Guido van Rossum687dd131993-05-17 08:34:16 +00008464#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8466 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008467 case 0: how = SEEK_SET; break;
8468 case 1: how = SEEK_CUR; break;
8469 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008470 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008471#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008472
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008474 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008475#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008476 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008477#else
Larry Hastings2f936352014-08-05 14:04:04 +10008478 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008479#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008480 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008482 if (result < 0)
8483 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008484
Larry Hastings2f936352014-08-05 14:04:04 +10008485 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008486}
8487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008488
Larry Hastings2f936352014-08-05 14:04:04 +10008489/*[clinic input]
8490os.read
8491 fd: int
8492 length: Py_ssize_t
8493 /
8494
8495Read from a file descriptor. Returns a bytes object.
8496[clinic start generated code]*/
8497
Larry Hastings2f936352014-08-05 14:04:04 +10008498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008499os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8500/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008501{
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 Py_ssize_t n;
8503 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008504
8505 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008506 errno = EINVAL;
8507 return posix_error();
8508 }
Larry Hastings2f936352014-08-05 14:04:04 +10008509
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008510 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008511
8512 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 if (buffer == NULL)
8514 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008515
Victor Stinner66aab0c2015-03-19 22:53:20 +01008516 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8517 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008519 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 }
Larry Hastings2f936352014-08-05 14:04:04 +10008521
8522 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008523 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008524
Victor Stinner8c62be82010-05-06 00:08:46 +00008525 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008526}
8527
Ross Lagerwall7807c352011-03-17 20:20:30 +02008528#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008529 || defined(__APPLE__))) \
8530 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8531 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8532static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008533iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008534{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008535 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008536
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008537 *iov = PyMem_New(struct iovec, cnt);
8538 if (*iov == NULL) {
8539 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008540 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008541 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008542
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008543 *buf = PyMem_New(Py_buffer, cnt);
8544 if (*buf == NULL) {
8545 PyMem_Del(*iov);
8546 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008547 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008548 }
8549
8550 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008551 PyObject *item = PySequence_GetItem(seq, i);
8552 if (item == NULL)
8553 goto fail;
8554 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8555 Py_DECREF(item);
8556 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008557 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008558 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008559 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008560 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008561 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008562 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008563
8564fail:
8565 PyMem_Del(*iov);
8566 for (j = 0; j < i; j++) {
8567 PyBuffer_Release(&(*buf)[j]);
8568 }
8569 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008570 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008571}
8572
8573static void
8574iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8575{
8576 int i;
8577 PyMem_Del(iov);
8578 for (i = 0; i < cnt; i++) {
8579 PyBuffer_Release(&buf[i]);
8580 }
8581 PyMem_Del(buf);
8582}
8583#endif
8584
Larry Hastings2f936352014-08-05 14:04:04 +10008585
Ross Lagerwall7807c352011-03-17 20:20:30 +02008586#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008587/*[clinic input]
8588os.readv -> Py_ssize_t
8589
8590 fd: int
8591 buffers: object
8592 /
8593
8594Read from a file descriptor fd into an iterable of buffers.
8595
8596The buffers should be mutable buffers accepting bytes.
8597readv will transfer data into each buffer until it is full
8598and then move on to the next buffer in the sequence to hold
8599the rest of the data.
8600
8601readv returns the total number of bytes read,
8602which may be less than the total capacity of all the buffers.
8603[clinic start generated code]*/
8604
Larry Hastings2f936352014-08-05 14:04:04 +10008605static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008606os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8607/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008608{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008609 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008610 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008611 struct iovec *iov;
8612 Py_buffer *buf;
8613
Larry Hastings2f936352014-08-05 14:04:04 +10008614 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008615 PyErr_SetString(PyExc_TypeError,
8616 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008617 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008618 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008619
Larry Hastings2f936352014-08-05 14:04:04 +10008620 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008621 if (cnt < 0)
8622 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008623
8624 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8625 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008626
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008627 do {
8628 Py_BEGIN_ALLOW_THREADS
8629 n = readv(fd, iov, cnt);
8630 Py_END_ALLOW_THREADS
8631 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008632
8633 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008634 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 if (!async_err)
8636 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008637 return -1;
8638 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008639
Larry Hastings2f936352014-08-05 14:04:04 +10008640 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008641}
Larry Hastings2f936352014-08-05 14:04:04 +10008642#endif /* HAVE_READV */
8643
Ross Lagerwall7807c352011-03-17 20:20:30 +02008644
8645#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008646/*[clinic input]
8647# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8648os.pread
8649
8650 fd: int
8651 length: int
8652 offset: Py_off_t
8653 /
8654
8655Read a number of bytes from a file descriptor starting at a particular offset.
8656
8657Read length bytes from file descriptor fd, starting at offset bytes from
8658the beginning of the file. The file offset remains unchanged.
8659[clinic start generated code]*/
8660
Larry Hastings2f936352014-08-05 14:04:04 +10008661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008662os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8663/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008664{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008665 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008666 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008667 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008668
Larry Hastings2f936352014-08-05 14:04:04 +10008669 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008670 errno = EINVAL;
8671 return posix_error();
8672 }
Larry Hastings2f936352014-08-05 14:04:04 +10008673 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008674 if (buffer == NULL)
8675 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008676
8677 do {
8678 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008679 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008681 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008682 Py_END_ALLOW_THREADS
8683 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8684
Ross Lagerwall7807c352011-03-17 20:20:30 +02008685 if (n < 0) {
8686 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008687 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008688 }
Larry Hastings2f936352014-08-05 14:04:04 +10008689 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008690 _PyBytes_Resize(&buffer, n);
8691 return buffer;
8692}
Larry Hastings2f936352014-08-05 14:04:04 +10008693#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008694
Pablo Galindo4defba32018-01-27 16:16:37 +00008695#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8696/*[clinic input]
8697os.preadv -> Py_ssize_t
8698
8699 fd: int
8700 buffers: object
8701 offset: Py_off_t
8702 flags: int = 0
8703 /
8704
8705Reads from a file descriptor into a number of mutable bytes-like objects.
8706
8707Combines the functionality of readv() and pread(). As readv(), it will
8708transfer data into each buffer until it is full and then move on to the next
8709buffer in the sequence to hold the rest of the data. Its fourth argument,
8710specifies the file offset at which the input operation is to be performed. It
8711will return the total number of bytes read (which can be less than the total
8712capacity of all the objects).
8713
8714The flags argument contains a bitwise OR of zero or more of the following flags:
8715
8716- RWF_HIPRI
8717- RWF_NOWAIT
8718
8719Using non-zero flags requires Linux 4.6 or newer.
8720[clinic start generated code]*/
8721
8722static Py_ssize_t
8723os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8724 int flags)
8725/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8726{
8727 Py_ssize_t cnt, n;
8728 int async_err = 0;
8729 struct iovec *iov;
8730 Py_buffer *buf;
8731
8732 if (!PySequence_Check(buffers)) {
8733 PyErr_SetString(PyExc_TypeError,
8734 "preadv2() arg 2 must be a sequence");
8735 return -1;
8736 }
8737
8738 cnt = PySequence_Size(buffers);
8739 if (cnt < 0) {
8740 return -1;
8741 }
8742
8743#ifndef HAVE_PREADV2
8744 if(flags != 0) {
8745 argument_unavailable_error("preadv2", "flags");
8746 return -1;
8747 }
8748#endif
8749
8750 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8751 return -1;
8752 }
8753#ifdef HAVE_PREADV2
8754 do {
8755 Py_BEGIN_ALLOW_THREADS
8756 _Py_BEGIN_SUPPRESS_IPH
8757 n = preadv2(fd, iov, cnt, offset, flags);
8758 _Py_END_SUPPRESS_IPH
8759 Py_END_ALLOW_THREADS
8760 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8761#else
8762 do {
8763 Py_BEGIN_ALLOW_THREADS
8764 _Py_BEGIN_SUPPRESS_IPH
8765 n = preadv(fd, iov, cnt, offset);
8766 _Py_END_SUPPRESS_IPH
8767 Py_END_ALLOW_THREADS
8768 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8769#endif
8770
8771 iov_cleanup(iov, buf, cnt);
8772 if (n < 0) {
8773 if (!async_err) {
8774 posix_error();
8775 }
8776 return -1;
8777 }
8778
8779 return n;
8780}
8781#endif /* HAVE_PREADV */
8782
Larry Hastings2f936352014-08-05 14:04:04 +10008783
8784/*[clinic input]
8785os.write -> Py_ssize_t
8786
8787 fd: int
8788 data: Py_buffer
8789 /
8790
8791Write a bytes object to a file descriptor.
8792[clinic start generated code]*/
8793
Larry Hastings2f936352014-08-05 14:04:04 +10008794static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008795os_write_impl(PyObject *module, int fd, Py_buffer *data)
8796/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008797{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008798 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008799}
8800
8801#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008802PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008803"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008804sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008805 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008806Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008807
Larry Hastings2f936352014-08-05 14:04:04 +10008808/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008809static PyObject *
8810posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8811{
8812 int in, out;
8813 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008814 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008815 off_t offset;
8816
8817#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8818#ifndef __APPLE__
8819 Py_ssize_t len;
8820#endif
8821 PyObject *headers = NULL, *trailers = NULL;
8822 Py_buffer *hbuf, *tbuf;
8823 off_t sbytes;
8824 struct sf_hdtr sf;
8825 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008826 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008827 static char *keywords[] = {"out", "in",
8828 "offset", "count",
8829 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008830
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008831 sf.headers = NULL;
8832 sf.trailers = NULL;
8833
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008834#ifdef __APPLE__
8835 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008836 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008837#else
8838 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008839 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008840#endif
8841 &headers, &trailers, &flags))
8842 return NULL;
8843 if (headers != NULL) {
8844 if (!PySequence_Check(headers)) {
8845 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008846 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008847 return NULL;
8848 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008849 Py_ssize_t i = PySequence_Size(headers);
8850 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008851 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008852 if (i > INT_MAX) {
8853 PyErr_SetString(PyExc_OverflowError,
8854 "sendfile() header is too large");
8855 return NULL;
8856 }
8857 if (i > 0) {
8858 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008859 if (iov_setup(&(sf.headers), &hbuf,
8860 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008861 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008862#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008863 for (i = 0; i < sf.hdr_cnt; i++) {
8864 Py_ssize_t blen = sf.headers[i].iov_len;
8865# define OFF_T_MAX 0x7fffffffffffffff
8866 if (sbytes >= OFF_T_MAX - blen) {
8867 PyErr_SetString(PyExc_OverflowError,
8868 "sendfile() header is too large");
8869 return NULL;
8870 }
8871 sbytes += blen;
8872 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008873#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008874 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008875 }
8876 }
8877 if (trailers != NULL) {
8878 if (!PySequence_Check(trailers)) {
8879 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008880 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008881 return NULL;
8882 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008883 Py_ssize_t i = PySequence_Size(trailers);
8884 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008885 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008886 if (i > INT_MAX) {
8887 PyErr_SetString(PyExc_OverflowError,
8888 "sendfile() trailer is too large");
8889 return NULL;
8890 }
8891 if (i > 0) {
8892 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008893 if (iov_setup(&(sf.trailers), &tbuf,
8894 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008895 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008896 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008897 }
8898 }
8899
Steve Dower8fc89802015-04-12 00:26:27 -04008900 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008901 do {
8902 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008903#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008904 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008905#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008906 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008907#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008908 Py_END_ALLOW_THREADS
8909 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008910 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008911
8912 if (sf.headers != NULL)
8913 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8914 if (sf.trailers != NULL)
8915 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8916
8917 if (ret < 0) {
8918 if ((errno == EAGAIN) || (errno == EBUSY)) {
8919 if (sbytes != 0) {
8920 // some data has been sent
8921 goto done;
8922 }
8923 else {
8924 // no data has been sent; upper application is supposed
8925 // to retry on EAGAIN or EBUSY
8926 return posix_error();
8927 }
8928 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008929 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008930 }
8931 goto done;
8932
8933done:
8934 #if !defined(HAVE_LARGEFILE_SUPPORT)
8935 return Py_BuildValue("l", sbytes);
8936 #else
8937 return Py_BuildValue("L", sbytes);
8938 #endif
8939
8940#else
8941 Py_ssize_t count;
8942 PyObject *offobj;
8943 static char *keywords[] = {"out", "in",
8944 "offset", "count", NULL};
8945 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8946 keywords, &out, &in, &offobj, &count))
8947 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008948#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008949 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008950 do {
8951 Py_BEGIN_ALLOW_THREADS
8952 ret = sendfile(out, in, NULL, count);
8953 Py_END_ALLOW_THREADS
8954 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008955 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008956 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008957 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008958 }
8959#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008960 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008961 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008962
8963 do {
8964 Py_BEGIN_ALLOW_THREADS
8965 ret = sendfile(out, in, &offset, count);
8966 Py_END_ALLOW_THREADS
8967 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008968 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008969 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008970 return Py_BuildValue("n", ret);
8971#endif
8972}
Larry Hastings2f936352014-08-05 14:04:04 +10008973#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008974
Larry Hastings2f936352014-08-05 14:04:04 +10008975
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008976#if defined(__APPLE__)
8977/*[clinic input]
8978os._fcopyfile
8979
8980 infd: int
8981 outfd: int
8982 flags: int
8983 /
8984
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008985Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008986[clinic start generated code]*/
8987
8988static PyObject *
8989os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008990/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008991{
8992 int ret;
8993
8994 Py_BEGIN_ALLOW_THREADS
8995 ret = fcopyfile(infd, outfd, NULL, flags);
8996 Py_END_ALLOW_THREADS
8997 if (ret < 0)
8998 return posix_error();
8999 Py_RETURN_NONE;
9000}
9001#endif
9002
9003
Larry Hastings2f936352014-08-05 14:04:04 +10009004/*[clinic input]
9005os.fstat
9006
9007 fd : int
9008
9009Perform a stat system call on the given file descriptor.
9010
9011Like stat(), but for an open file descriptor.
9012Equivalent to os.stat(fd).
9013[clinic start generated code]*/
9014
Larry Hastings2f936352014-08-05 14:04:04 +10009015static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009016os_fstat_impl(PyObject *module, int fd)
9017/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009018{
Victor Stinner8c62be82010-05-06 00:08:46 +00009019 STRUCT_STAT st;
9020 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009021 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009022
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009023 do {
9024 Py_BEGIN_ALLOW_THREADS
9025 res = FSTAT(fd, &st);
9026 Py_END_ALLOW_THREADS
9027 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009029#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009030 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009031#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009032 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009033#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 }
Tim Peters5aa91602002-01-30 05:46:57 +00009035
Victor Stinner4195b5c2012-02-08 23:03:19 +01009036 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009037}
9038
Larry Hastings2f936352014-08-05 14:04:04 +10009039
9040/*[clinic input]
9041os.isatty -> bool
9042 fd: int
9043 /
9044
9045Return True if the fd is connected to a terminal.
9046
9047Return True if the file descriptor is an open file descriptor
9048connected to the slave end of a terminal.
9049[clinic start generated code]*/
9050
Larry Hastings2f936352014-08-05 14:04:04 +10009051static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009052os_isatty_impl(PyObject *module, int fd)
9053/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009054{
Steve Dower8fc89802015-04-12 00:26:27 -04009055 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009056 _Py_BEGIN_SUPPRESS_IPH
9057 return_value = isatty(fd);
9058 _Py_END_SUPPRESS_IPH
9059 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009060}
9061
9062
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009063#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009064/*[clinic input]
9065os.pipe
9066
9067Create a pipe.
9068
9069Returns a tuple of two file descriptors:
9070 (read_fd, write_fd)
9071[clinic start generated code]*/
9072
Larry Hastings2f936352014-08-05 14:04:04 +10009073static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009074os_pipe_impl(PyObject *module)
9075/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009076{
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009078#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009080 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009082#else
9083 int res;
9084#endif
9085
9086#ifdef MS_WINDOWS
9087 attr.nLength = sizeof(attr);
9088 attr.lpSecurityDescriptor = NULL;
9089 attr.bInheritHandle = FALSE;
9090
9091 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009092 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009093 ok = CreatePipe(&read, &write, &attr, 0);
9094 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009095 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9096 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009097 if (fds[0] == -1 || fds[1] == -1) {
9098 CloseHandle(read);
9099 CloseHandle(write);
9100 ok = 0;
9101 }
9102 }
Steve Dowerc3630612016-11-19 18:41:16 -08009103 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009104 Py_END_ALLOW_THREADS
9105
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009107 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009108#else
9109
9110#ifdef HAVE_PIPE2
9111 Py_BEGIN_ALLOW_THREADS
9112 res = pipe2(fds, O_CLOEXEC);
9113 Py_END_ALLOW_THREADS
9114
9115 if (res != 0 && errno == ENOSYS)
9116 {
9117#endif
9118 Py_BEGIN_ALLOW_THREADS
9119 res = pipe(fds);
9120 Py_END_ALLOW_THREADS
9121
9122 if (res == 0) {
9123 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9124 close(fds[0]);
9125 close(fds[1]);
9126 return NULL;
9127 }
9128 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9129 close(fds[0]);
9130 close(fds[1]);
9131 return NULL;
9132 }
9133 }
9134#ifdef HAVE_PIPE2
9135 }
9136#endif
9137
9138 if (res != 0)
9139 return PyErr_SetFromErrno(PyExc_OSError);
9140#endif /* !MS_WINDOWS */
9141 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009142}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009143#endif /* HAVE_PIPE */
9144
Larry Hastings2f936352014-08-05 14:04:04 +10009145
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009146#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009147/*[clinic input]
9148os.pipe2
9149
9150 flags: int
9151 /
9152
9153Create a pipe with flags set atomically.
9154
9155Returns a tuple of two file descriptors:
9156 (read_fd, write_fd)
9157
9158flags can be constructed by ORing together one or more of these values:
9159O_NONBLOCK, O_CLOEXEC.
9160[clinic start generated code]*/
9161
Larry Hastings2f936352014-08-05 14:04:04 +10009162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009163os_pipe2_impl(PyObject *module, int flags)
9164/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009165{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009166 int fds[2];
9167 int res;
9168
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009169 res = pipe2(fds, flags);
9170 if (res != 0)
9171 return posix_error();
9172 return Py_BuildValue("(ii)", fds[0], fds[1]);
9173}
9174#endif /* HAVE_PIPE2 */
9175
Larry Hastings2f936352014-08-05 14:04:04 +10009176
Ross Lagerwall7807c352011-03-17 20:20:30 +02009177#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009178/*[clinic input]
9179os.writev -> Py_ssize_t
9180 fd: int
9181 buffers: object
9182 /
9183
9184Iterate over buffers, and write the contents of each to a file descriptor.
9185
9186Returns the total number of bytes written.
9187buffers must be a sequence of bytes-like objects.
9188[clinic start generated code]*/
9189
Larry Hastings2f936352014-08-05 14:04:04 +10009190static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009191os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9192/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009193{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009194 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009195 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009196 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009197 struct iovec *iov;
9198 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009199
9200 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009201 PyErr_SetString(PyExc_TypeError,
9202 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009203 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009204 }
Larry Hastings2f936352014-08-05 14:04:04 +10009205 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009206 if (cnt < 0)
9207 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009208
Larry Hastings2f936352014-08-05 14:04:04 +10009209 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9210 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009211 }
9212
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009213 do {
9214 Py_BEGIN_ALLOW_THREADS
9215 result = writev(fd, iov, cnt);
9216 Py_END_ALLOW_THREADS
9217 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009218
9219 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009220 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009221 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009222
Georg Brandl306336b2012-06-24 12:55:33 +02009223 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009224}
Larry Hastings2f936352014-08-05 14:04:04 +10009225#endif /* HAVE_WRITEV */
9226
9227
9228#ifdef HAVE_PWRITE
9229/*[clinic input]
9230os.pwrite -> Py_ssize_t
9231
9232 fd: int
9233 buffer: Py_buffer
9234 offset: Py_off_t
9235 /
9236
9237Write bytes to a file descriptor starting at a particular offset.
9238
9239Write buffer to fd, starting at offset bytes from the beginning of
9240the file. Returns the number of bytes writte. Does not change the
9241current file offset.
9242[clinic start generated code]*/
9243
Larry Hastings2f936352014-08-05 14:04:04 +10009244static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009245os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9246/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009247{
9248 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009249 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009250
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009251 do {
9252 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009253 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009254 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009255 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009256 Py_END_ALLOW_THREADS
9257 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009258
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009259 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009260 posix_error();
9261 return size;
9262}
9263#endif /* HAVE_PWRITE */
9264
Pablo Galindo4defba32018-01-27 16:16:37 +00009265#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9266/*[clinic input]
9267os.pwritev -> Py_ssize_t
9268
9269 fd: int
9270 buffers: object
9271 offset: Py_off_t
9272 flags: int = 0
9273 /
9274
9275Writes the contents of bytes-like objects to a file descriptor at a given offset.
9276
9277Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9278of bytes-like objects. Buffers are processed in array order. Entire contents of first
9279buffer is written before proceeding to second, and so on. The operating system may
9280set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9281This function writes the contents of each object to the file descriptor and returns
9282the total number of bytes written.
9283
9284The flags argument contains a bitwise OR of zero or more of the following flags:
9285
9286- RWF_DSYNC
9287- RWF_SYNC
9288
9289Using non-zero flags requires Linux 4.7 or newer.
9290[clinic start generated code]*/
9291
9292static Py_ssize_t
9293os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9294 int flags)
9295/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9296{
9297 Py_ssize_t cnt;
9298 Py_ssize_t result;
9299 int async_err = 0;
9300 struct iovec *iov;
9301 Py_buffer *buf;
9302
9303 if (!PySequence_Check(buffers)) {
9304 PyErr_SetString(PyExc_TypeError,
9305 "pwritev() arg 2 must be a sequence");
9306 return -1;
9307 }
9308
9309 cnt = PySequence_Size(buffers);
9310 if (cnt < 0) {
9311 return -1;
9312 }
9313
9314#ifndef HAVE_PWRITEV2
9315 if(flags != 0) {
9316 argument_unavailable_error("pwritev2", "flags");
9317 return -1;
9318 }
9319#endif
9320
9321 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9322 return -1;
9323 }
9324#ifdef HAVE_PWRITEV2
9325 do {
9326 Py_BEGIN_ALLOW_THREADS
9327 _Py_BEGIN_SUPPRESS_IPH
9328 result = pwritev2(fd, iov, cnt, offset, flags);
9329 _Py_END_SUPPRESS_IPH
9330 Py_END_ALLOW_THREADS
9331 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9332#else
9333 do {
9334 Py_BEGIN_ALLOW_THREADS
9335 _Py_BEGIN_SUPPRESS_IPH
9336 result = pwritev(fd, iov, cnt, offset);
9337 _Py_END_SUPPRESS_IPH
9338 Py_END_ALLOW_THREADS
9339 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9340#endif
9341
9342 iov_cleanup(iov, buf, cnt);
9343 if (result < 0) {
9344 if (!async_err) {
9345 posix_error();
9346 }
9347 return -1;
9348 }
9349
9350 return result;
9351}
9352#endif /* HAVE_PWRITEV */
9353
9354
9355
Larry Hastings2f936352014-08-05 14:04:04 +10009356
9357#ifdef HAVE_MKFIFO
9358/*[clinic input]
9359os.mkfifo
9360
9361 path: path_t
9362 mode: int=0o666
9363 *
9364 dir_fd: dir_fd(requires='mkfifoat')=None
9365
9366Create a "fifo" (a POSIX named pipe).
9367
9368If dir_fd is not None, it should be a file descriptor open to a directory,
9369 and path should be relative; path will then be relative to that directory.
9370dir_fd may not be implemented on your platform.
9371 If it is unavailable, using it will raise a NotImplementedError.
9372[clinic start generated code]*/
9373
Larry Hastings2f936352014-08-05 14:04:04 +10009374static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009375os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9376/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009377{
9378 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009379 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009380
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009381 do {
9382 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009383#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009384 if (dir_fd != DEFAULT_DIR_FD)
9385 result = mkfifoat(dir_fd, path->narrow, mode);
9386 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009387#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009388 result = mkfifo(path->narrow, mode);
9389 Py_END_ALLOW_THREADS
9390 } while (result != 0 && errno == EINTR &&
9391 !(async_err = PyErr_CheckSignals()));
9392 if (result != 0)
9393 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009394
9395 Py_RETURN_NONE;
9396}
9397#endif /* HAVE_MKFIFO */
9398
9399
9400#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9401/*[clinic input]
9402os.mknod
9403
9404 path: path_t
9405 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009406 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009407 *
9408 dir_fd: dir_fd(requires='mknodat')=None
9409
9410Create a node in the file system.
9411
9412Create a node in the file system (file, device special file or named pipe)
9413at path. mode specifies both the permissions to use and the
9414type of node to be created, being combined (bitwise OR) with one of
9415S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9416device defines the newly created device special file (probably using
9417os.makedev()). Otherwise device is ignored.
9418
9419If dir_fd is not None, it should be a file descriptor open to a directory,
9420 and path should be relative; path will then be relative to that directory.
9421dir_fd may not be implemented on your platform.
9422 If it is unavailable, using it will raise a NotImplementedError.
9423[clinic start generated code]*/
9424
Larry Hastings2f936352014-08-05 14:04:04 +10009425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009426os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009427 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009428/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009429{
9430 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009431 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009432
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009433 do {
9434 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009435#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009436 if (dir_fd != DEFAULT_DIR_FD)
9437 result = mknodat(dir_fd, path->narrow, mode, device);
9438 else
Larry Hastings2f936352014-08-05 14:04:04 +10009439#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009440 result = mknod(path->narrow, mode, device);
9441 Py_END_ALLOW_THREADS
9442 } while (result != 0 && errno == EINTR &&
9443 !(async_err = PyErr_CheckSignals()));
9444 if (result != 0)
9445 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009446
9447 Py_RETURN_NONE;
9448}
9449#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9450
9451
9452#ifdef HAVE_DEVICE_MACROS
9453/*[clinic input]
9454os.major -> unsigned_int
9455
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009456 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009457 /
9458
9459Extracts a device major number from a raw device number.
9460[clinic start generated code]*/
9461
Larry Hastings2f936352014-08-05 14:04:04 +10009462static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009463os_major_impl(PyObject *module, dev_t device)
9464/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009465{
9466 return major(device);
9467}
9468
9469
9470/*[clinic input]
9471os.minor -> unsigned_int
9472
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009473 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009474 /
9475
9476Extracts a device minor number from a raw device number.
9477[clinic start generated code]*/
9478
Larry Hastings2f936352014-08-05 14:04:04 +10009479static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009480os_minor_impl(PyObject *module, dev_t device)
9481/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009482{
9483 return minor(device);
9484}
9485
9486
9487/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009488os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009489
9490 major: int
9491 minor: int
9492 /
9493
9494Composes a raw device number from the major and minor device numbers.
9495[clinic start generated code]*/
9496
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009497static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009498os_makedev_impl(PyObject *module, int major, int minor)
9499/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009500{
9501 return makedev(major, minor);
9502}
9503#endif /* HAVE_DEVICE_MACROS */
9504
9505
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009506#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009507/*[clinic input]
9508os.ftruncate
9509
9510 fd: int
9511 length: Py_off_t
9512 /
9513
9514Truncate a file, specified by file descriptor, to a specific length.
9515[clinic start generated code]*/
9516
Larry Hastings2f936352014-08-05 14:04:04 +10009517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009518os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9519/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009520{
9521 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009522 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009523
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009524 do {
9525 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009526 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009527#ifdef MS_WINDOWS
9528 result = _chsize_s(fd, length);
9529#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009530 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009531#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009532 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009533 Py_END_ALLOW_THREADS
9534 } while (result != 0 && errno == EINTR &&
9535 !(async_err = PyErr_CheckSignals()));
9536 if (result != 0)
9537 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009538 Py_RETURN_NONE;
9539}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009540#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009541
9542
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009543#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009544/*[clinic input]
9545os.truncate
9546 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9547 length: Py_off_t
9548
9549Truncate a file, specified by path, to a specific length.
9550
9551On some platforms, path may also be specified as an open file descriptor.
9552 If this functionality is unavailable, using it raises an exception.
9553[clinic start generated code]*/
9554
Larry Hastings2f936352014-08-05 14:04:04 +10009555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009556os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9557/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009558{
9559 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009560#ifdef MS_WINDOWS
9561 int fd;
9562#endif
9563
9564 if (path->fd != -1)
9565 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009566
9567 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009568 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009569#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009570 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009571 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009572 result = -1;
9573 else {
9574 result = _chsize_s(fd, length);
9575 close(fd);
9576 if (result < 0)
9577 errno = result;
9578 }
9579#else
9580 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009581#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009582 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009583 Py_END_ALLOW_THREADS
9584 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009585 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009586
9587 Py_RETURN_NONE;
9588}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009589#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009590
Ross Lagerwall7807c352011-03-17 20:20:30 +02009591
Victor Stinnerd6b17692014-09-30 12:20:05 +02009592/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9593 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9594 defined, which is the case in Python on AIX. AIX bug report:
9595 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9596#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9597# define POSIX_FADVISE_AIX_BUG
9598#endif
9599
Victor Stinnerec39e262014-09-30 12:35:58 +02009600
Victor Stinnerd6b17692014-09-30 12:20:05 +02009601#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009602/*[clinic input]
9603os.posix_fallocate
9604
9605 fd: int
9606 offset: Py_off_t
9607 length: Py_off_t
9608 /
9609
9610Ensure a file has allocated at least a particular number of bytes on disk.
9611
9612Ensure that the file specified by fd encompasses a range of bytes
9613starting at offset bytes from the beginning and continuing for length bytes.
9614[clinic start generated code]*/
9615
Larry Hastings2f936352014-08-05 14:04:04 +10009616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009617os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009618 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009619/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009620{
9621 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009622 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009623
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009624 do {
9625 Py_BEGIN_ALLOW_THREADS
9626 result = posix_fallocate(fd, offset, length);
9627 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009628 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9629
9630 if (result == 0)
9631 Py_RETURN_NONE;
9632
9633 if (async_err)
9634 return NULL;
9635
9636 errno = result;
9637 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009638}
Victor Stinnerec39e262014-09-30 12:35:58 +02009639#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009640
Ross Lagerwall7807c352011-03-17 20:20:30 +02009641
Victor Stinnerd6b17692014-09-30 12:20:05 +02009642#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009643/*[clinic input]
9644os.posix_fadvise
9645
9646 fd: int
9647 offset: Py_off_t
9648 length: Py_off_t
9649 advice: int
9650 /
9651
9652Announce an intention to access data in a specific pattern.
9653
9654Announce an intention to access data in a specific pattern, thus allowing
9655the kernel to make optimizations.
9656The advice applies to the region of the file specified by fd starting at
9657offset and continuing for length bytes.
9658advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9659POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9660POSIX_FADV_DONTNEED.
9661[clinic start generated code]*/
9662
Larry Hastings2f936352014-08-05 14:04:04 +10009663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009664os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009665 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009666/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009667{
9668 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009669 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009670
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009671 do {
9672 Py_BEGIN_ALLOW_THREADS
9673 result = posix_fadvise(fd, offset, length, advice);
9674 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009675 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9676
9677 if (result == 0)
9678 Py_RETURN_NONE;
9679
9680 if (async_err)
9681 return NULL;
9682
9683 errno = result;
9684 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009685}
Victor Stinnerec39e262014-09-30 12:35:58 +02009686#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009687
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009688#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009689
Fred Drake762e2061999-08-26 17:23:54 +00009690/* Save putenv() parameters as values here, so we can collect them when they
9691 * get re-set with another call for the same key. */
9692static PyObject *posix_putenv_garbage;
9693
Larry Hastings2f936352014-08-05 14:04:04 +10009694static void
9695posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009696{
Larry Hastings2f936352014-08-05 14:04:04 +10009697 /* Install the first arg and newstr in posix_putenv_garbage;
9698 * this will cause previous value to be collected. This has to
9699 * happen after the real putenv() call because the old value
9700 * was still accessible until then. */
9701 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9702 /* really not much we can do; just leak */
9703 PyErr_Clear();
9704 else
9705 Py_DECREF(value);
9706}
9707
9708
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009709#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009710/*[clinic input]
9711os.putenv
9712
9713 name: unicode
9714 value: unicode
9715 /
9716
9717Change or add an environment variable.
9718[clinic start generated code]*/
9719
Larry Hastings2f936352014-08-05 14:04:04 +10009720static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009721os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9722/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009723{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009724 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009725 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009726
Serhiy Storchaka77703942017-06-25 07:33:01 +03009727 /* Search from index 1 because on Windows starting '=' is allowed for
9728 defining hidden environment variables. */
9729 if (PyUnicode_GET_LENGTH(name) == 0 ||
9730 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9731 {
9732 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9733 return NULL;
9734 }
Larry Hastings2f936352014-08-05 14:04:04 +10009735 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9736 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009737 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009738 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009739
9740 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9741 if (env == NULL)
9742 goto error;
9743 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009744 PyErr_Format(PyExc_ValueError,
9745 "the environment variable is longer than %u characters",
9746 _MAX_ENV);
9747 goto error;
9748 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009749 if (wcslen(env) != (size_t)size) {
9750 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009751 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009752 }
9753
Larry Hastings2f936352014-08-05 14:04:04 +10009754 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009756 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009758
Larry Hastings2f936352014-08-05 14:04:04 +10009759 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009760 Py_RETURN_NONE;
9761
9762error:
Larry Hastings2f936352014-08-05 14:04:04 +10009763 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009764 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009765}
Larry Hastings2f936352014-08-05 14:04:04 +10009766#else /* MS_WINDOWS */
9767/*[clinic input]
9768os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009769
Larry Hastings2f936352014-08-05 14:04:04 +10009770 name: FSConverter
9771 value: FSConverter
9772 /
9773
9774Change or add an environment variable.
9775[clinic start generated code]*/
9776
Larry Hastings2f936352014-08-05 14:04:04 +10009777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009778os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9779/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009780{
9781 PyObject *bytes = NULL;
9782 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009783 const char *name_string = PyBytes_AS_STRING(name);
9784 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009785
Serhiy Storchaka77703942017-06-25 07:33:01 +03009786 if (strchr(name_string, '=') != NULL) {
9787 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9788 return NULL;
9789 }
Larry Hastings2f936352014-08-05 14:04:04 +10009790 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9791 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009792 return NULL;
9793 }
9794
9795 env = PyBytes_AS_STRING(bytes);
9796 if (putenv(env)) {
9797 Py_DECREF(bytes);
9798 return posix_error();
9799 }
9800
9801 posix_putenv_garbage_setitem(name, bytes);
9802 Py_RETURN_NONE;
9803}
9804#endif /* MS_WINDOWS */
9805#endif /* HAVE_PUTENV */
9806
9807
9808#ifdef HAVE_UNSETENV
9809/*[clinic input]
9810os.unsetenv
9811 name: FSConverter
9812 /
9813
9814Delete an environment variable.
9815[clinic start generated code]*/
9816
Larry Hastings2f936352014-08-05 14:04:04 +10009817static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009818os_unsetenv_impl(PyObject *module, PyObject *name)
9819/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009820{
Victor Stinner984890f2011-11-24 13:53:38 +01009821#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009822 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009823#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009824
Victor Stinner984890f2011-11-24 13:53:38 +01009825#ifdef HAVE_BROKEN_UNSETENV
9826 unsetenv(PyBytes_AS_STRING(name));
9827#else
Victor Stinner65170952011-11-22 22:16:17 +01009828 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009829 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009830 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009831#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009832
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 /* Remove the key from posix_putenv_garbage;
9834 * this will cause it to be collected. This has to
9835 * happen after the real unsetenv() call because the
9836 * old value was still accessible until then.
9837 */
Victor Stinner65170952011-11-22 22:16:17 +01009838 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02009840 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
9841 return NULL;
9842 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 PyErr_Clear();
9844 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009845 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009846}
Larry Hastings2f936352014-08-05 14:04:04 +10009847#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009848
Larry Hastings2f936352014-08-05 14:04:04 +10009849
9850/*[clinic input]
9851os.strerror
9852
9853 code: int
9854 /
9855
9856Translate an error code to a message string.
9857[clinic start generated code]*/
9858
Larry Hastings2f936352014-08-05 14:04:04 +10009859static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009860os_strerror_impl(PyObject *module, int code)
9861/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009862{
9863 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 if (message == NULL) {
9865 PyErr_SetString(PyExc_ValueError,
9866 "strerror() argument out of range");
9867 return NULL;
9868 }
Victor Stinner1b579672011-12-17 05:47:23 +01009869 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009870}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009871
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009872
Guido van Rossumc9641791998-08-04 15:26:23 +00009873#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009874#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009875/*[clinic input]
9876os.WCOREDUMP -> bool
9877
9878 status: int
9879 /
9880
9881Return True if the process returning status was dumped to a core file.
9882[clinic start generated code]*/
9883
Larry Hastings2f936352014-08-05 14:04:04 +10009884static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009885os_WCOREDUMP_impl(PyObject *module, int status)
9886/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009887{
9888 WAIT_TYPE wait_status;
9889 WAIT_STATUS_INT(wait_status) = status;
9890 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009891}
9892#endif /* WCOREDUMP */
9893
Larry Hastings2f936352014-08-05 14:04:04 +10009894
Fred Drake106c1a02002-04-23 15:58:02 +00009895#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009896/*[clinic input]
9897os.WIFCONTINUED -> bool
9898
9899 status: int
9900
9901Return True if a particular process was continued from a job control stop.
9902
9903Return True if the process returning status was continued from a
9904job control stop.
9905[clinic start generated code]*/
9906
Larry Hastings2f936352014-08-05 14:04:04 +10009907static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009908os_WIFCONTINUED_impl(PyObject *module, int status)
9909/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009910{
9911 WAIT_TYPE wait_status;
9912 WAIT_STATUS_INT(wait_status) = status;
9913 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009914}
9915#endif /* WIFCONTINUED */
9916
Larry Hastings2f936352014-08-05 14:04:04 +10009917
Guido van Rossumc9641791998-08-04 15:26:23 +00009918#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009919/*[clinic input]
9920os.WIFSTOPPED -> bool
9921
9922 status: int
9923
9924Return True if the process returning status was stopped.
9925[clinic start generated code]*/
9926
Larry Hastings2f936352014-08-05 14:04:04 +10009927static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009928os_WIFSTOPPED_impl(PyObject *module, int status)
9929/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009930{
9931 WAIT_TYPE wait_status;
9932 WAIT_STATUS_INT(wait_status) = status;
9933 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009934}
9935#endif /* WIFSTOPPED */
9936
Larry Hastings2f936352014-08-05 14:04:04 +10009937
Guido van Rossumc9641791998-08-04 15:26:23 +00009938#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009939/*[clinic input]
9940os.WIFSIGNALED -> bool
9941
9942 status: int
9943
9944Return True if the process returning status was terminated by a signal.
9945[clinic start generated code]*/
9946
Larry Hastings2f936352014-08-05 14:04:04 +10009947static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009948os_WIFSIGNALED_impl(PyObject *module, int status)
9949/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009950{
9951 WAIT_TYPE wait_status;
9952 WAIT_STATUS_INT(wait_status) = status;
9953 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009954}
9955#endif /* WIFSIGNALED */
9956
Larry Hastings2f936352014-08-05 14:04:04 +10009957
Guido van Rossumc9641791998-08-04 15:26:23 +00009958#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009959/*[clinic input]
9960os.WIFEXITED -> bool
9961
9962 status: int
9963
9964Return True if the process returning status exited via the exit() system call.
9965[clinic start generated code]*/
9966
Larry Hastings2f936352014-08-05 14:04:04 +10009967static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009968os_WIFEXITED_impl(PyObject *module, int status)
9969/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009970{
9971 WAIT_TYPE wait_status;
9972 WAIT_STATUS_INT(wait_status) = status;
9973 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009974}
9975#endif /* WIFEXITED */
9976
Larry Hastings2f936352014-08-05 14:04:04 +10009977
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009978#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009979/*[clinic input]
9980os.WEXITSTATUS -> int
9981
9982 status: int
9983
9984Return the process return code from status.
9985[clinic start generated code]*/
9986
Larry Hastings2f936352014-08-05 14:04:04 +10009987static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009988os_WEXITSTATUS_impl(PyObject *module, int status)
9989/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009990{
9991 WAIT_TYPE wait_status;
9992 WAIT_STATUS_INT(wait_status) = status;
9993 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009994}
9995#endif /* WEXITSTATUS */
9996
Larry Hastings2f936352014-08-05 14:04:04 +10009997
Guido van Rossumc9641791998-08-04 15:26:23 +00009998#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009999/*[clinic input]
10000os.WTERMSIG -> int
10001
10002 status: int
10003
10004Return the signal that terminated the process that provided the status value.
10005[clinic start generated code]*/
10006
Larry Hastings2f936352014-08-05 14:04:04 +100010007static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010008os_WTERMSIG_impl(PyObject *module, int status)
10009/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010010{
10011 WAIT_TYPE wait_status;
10012 WAIT_STATUS_INT(wait_status) = status;
10013 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010014}
10015#endif /* WTERMSIG */
10016
Larry Hastings2f936352014-08-05 14:04:04 +100010017
Guido van Rossumc9641791998-08-04 15:26:23 +000010018#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010019/*[clinic input]
10020os.WSTOPSIG -> int
10021
10022 status: int
10023
10024Return the signal that stopped the process that provided the status value.
10025[clinic start generated code]*/
10026
Larry Hastings2f936352014-08-05 14:04:04 +100010027static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010028os_WSTOPSIG_impl(PyObject *module, int status)
10029/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010030{
10031 WAIT_TYPE wait_status;
10032 WAIT_STATUS_INT(wait_status) = status;
10033 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010034}
10035#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010036#endif /* HAVE_SYS_WAIT_H */
10037
10038
Thomas Wouters477c8d52006-05-27 19:21:47 +000010039#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010040#ifdef _SCO_DS
10041/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10042 needed definitions in sys/statvfs.h */
10043#define _SVID3
10044#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010045#include <sys/statvfs.h>
10046
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010047static PyObject*
10048_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010049 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 if (v == NULL)
10051 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010052
10053#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10055 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10056 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10057 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10058 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10059 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10060 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10061 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10062 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10063 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010064#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10066 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10067 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010068 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010070 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010072 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010074 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010076 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010078 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10080 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010081#endif
Michael Felt502d5512018-01-05 13:01:58 +010010082/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10083 * (issue #32390). */
10084#if defined(_AIX) && defined(_ALL_SOURCE)
10085 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10086#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010087 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010088#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010089 if (PyErr_Occurred()) {
10090 Py_DECREF(v);
10091 return NULL;
10092 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010093
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010095}
10096
Larry Hastings2f936352014-08-05 14:04:04 +100010097
10098/*[clinic input]
10099os.fstatvfs
10100 fd: int
10101 /
10102
10103Perform an fstatvfs system call on the given fd.
10104
10105Equivalent to statvfs(fd).
10106[clinic start generated code]*/
10107
Larry Hastings2f936352014-08-05 14:04:04 +100010108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010109os_fstatvfs_impl(PyObject *module, int fd)
10110/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010111{
10112 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010113 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010115
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010116 do {
10117 Py_BEGIN_ALLOW_THREADS
10118 result = fstatvfs(fd, &st);
10119 Py_END_ALLOW_THREADS
10120 } while (result != 0 && errno == EINTR &&
10121 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010122 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010123 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010124
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010126}
Larry Hastings2f936352014-08-05 14:04:04 +100010127#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010128
10129
Thomas Wouters477c8d52006-05-27 19:21:47 +000010130#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010131#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010132/*[clinic input]
10133os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010134
Larry Hastings2f936352014-08-05 14:04:04 +100010135 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10136
10137Perform a statvfs system call on the given path.
10138
10139path may always be specified as a string.
10140On some platforms, path may also be specified as an open file descriptor.
10141 If this functionality is unavailable, using it raises an exception.
10142[clinic start generated code]*/
10143
Larry Hastings2f936352014-08-05 14:04:04 +100010144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010145os_statvfs_impl(PyObject *module, path_t *path)
10146/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010147{
10148 int result;
10149 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010150
10151 Py_BEGIN_ALLOW_THREADS
10152#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010153 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010154#ifdef __APPLE__
10155 /* handle weak-linking on Mac OS X 10.3 */
10156 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010157 fd_specified("statvfs", path->fd);
10158 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010159 }
10160#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010161 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010162 }
10163 else
10164#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010165 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010166 Py_END_ALLOW_THREADS
10167
10168 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010169 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010170 }
10171
Larry Hastings2f936352014-08-05 14:04:04 +100010172 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010173}
Larry Hastings2f936352014-08-05 14:04:04 +100010174#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10175
Guido van Rossum94f6f721999-01-06 18:42:14 +000010176
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010177#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010178/*[clinic input]
10179os._getdiskusage
10180
Steve Dower23ad6d02018-02-22 10:39:10 -080010181 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010182
10183Return disk usage statistics about the given path as a (total, free) tuple.
10184[clinic start generated code]*/
10185
Larry Hastings2f936352014-08-05 14:04:04 +100010186static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010187os__getdiskusage_impl(PyObject *module, path_t *path)
10188/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010189{
10190 BOOL retval;
10191 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010192 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010193
10194 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010195 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010196 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010197 if (retval == 0) {
10198 if (GetLastError() == ERROR_DIRECTORY) {
10199 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010200
Joe Pamerc8c02492018-09-25 10:57:36 -040010201 dir_path = PyMem_New(wchar_t, path->length + 1);
10202 if (dir_path == NULL) {
10203 return PyErr_NoMemory();
10204 }
10205
10206 wcscpy_s(dir_path, path->length + 1, path->wide);
10207
10208 if (_dirnameW(dir_path) != -1) {
10209 Py_BEGIN_ALLOW_THREADS
10210 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10211 Py_END_ALLOW_THREADS
10212 }
10213 /* Record the last error in case it's modified by PyMem_Free. */
10214 err = GetLastError();
10215 PyMem_Free(dir_path);
10216 if (retval) {
10217 goto success;
10218 }
10219 }
10220 return PyErr_SetFromWindowsErr(err);
10221 }
10222
10223success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010224 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10225}
Larry Hastings2f936352014-08-05 14:04:04 +100010226#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010227
10228
Fred Drakec9680921999-12-13 16:37:25 +000010229/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10230 * It maps strings representing configuration variable names to
10231 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010232 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010233 * rarely-used constants. There are three separate tables that use
10234 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010235 *
10236 * This code is always included, even if none of the interfaces that
10237 * need it are included. The #if hackery needed to avoid it would be
10238 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010239 */
10240struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010241 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010242 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010243};
10244
Fred Drake12c6e2d1999-12-14 21:25:03 +000010245static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010246conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010247 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010248{
Christian Heimes217cfd12007-12-02 14:31:20 +000010249 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010250 int value = _PyLong_AsInt(arg);
10251 if (value == -1 && PyErr_Occurred())
10252 return 0;
10253 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010254 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010255 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010256 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010257 /* look up the value in the table using a binary search */
10258 size_t lo = 0;
10259 size_t mid;
10260 size_t hi = tablesize;
10261 int cmp;
10262 const char *confname;
10263 if (!PyUnicode_Check(arg)) {
10264 PyErr_SetString(PyExc_TypeError,
10265 "configuration names must be strings or integers");
10266 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010268 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010269 if (confname == NULL)
10270 return 0;
10271 while (lo < hi) {
10272 mid = (lo + hi) / 2;
10273 cmp = strcmp(confname, table[mid].name);
10274 if (cmp < 0)
10275 hi = mid;
10276 else if (cmp > 0)
10277 lo = mid + 1;
10278 else {
10279 *valuep = table[mid].value;
10280 return 1;
10281 }
10282 }
10283 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10284 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010286}
10287
10288
10289#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10290static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010291#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010293#endif
10294#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010296#endif
Fred Drakec9680921999-12-13 16:37:25 +000010297#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010342#ifdef _PC_ACL_ENABLED
10343 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10344#endif
10345#ifdef _PC_MIN_HOLE_SIZE
10346 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10347#endif
10348#ifdef _PC_ALLOC_SIZE_MIN
10349 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10350#endif
10351#ifdef _PC_REC_INCR_XFER_SIZE
10352 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10353#endif
10354#ifdef _PC_REC_MAX_XFER_SIZE
10355 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10356#endif
10357#ifdef _PC_REC_MIN_XFER_SIZE
10358 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10359#endif
10360#ifdef _PC_REC_XFER_ALIGN
10361 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10362#endif
10363#ifdef _PC_SYMLINK_MAX
10364 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10365#endif
10366#ifdef _PC_XATTR_ENABLED
10367 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10368#endif
10369#ifdef _PC_XATTR_EXISTS
10370 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10371#endif
10372#ifdef _PC_TIMESTAMP_RESOLUTION
10373 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10374#endif
Fred Drakec9680921999-12-13 16:37:25 +000010375};
10376
Fred Drakec9680921999-12-13 16:37:25 +000010377static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010378conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010379{
10380 return conv_confname(arg, valuep, posix_constants_pathconf,
10381 sizeof(posix_constants_pathconf)
10382 / sizeof(struct constdef));
10383}
10384#endif
10385
Larry Hastings2f936352014-08-05 14:04:04 +100010386
Fred Drakec9680921999-12-13 16:37:25 +000010387#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010388/*[clinic input]
10389os.fpathconf -> long
10390
10391 fd: int
10392 name: path_confname
10393 /
10394
10395Return the configuration limit name for the file descriptor fd.
10396
10397If there is no limit, return -1.
10398[clinic start generated code]*/
10399
Larry Hastings2f936352014-08-05 14:04:04 +100010400static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010401os_fpathconf_impl(PyObject *module, int fd, int name)
10402/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010403{
10404 long limit;
10405
10406 errno = 0;
10407 limit = fpathconf(fd, name);
10408 if (limit == -1 && errno != 0)
10409 posix_error();
10410
10411 return limit;
10412}
10413#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010414
10415
10416#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010417/*[clinic input]
10418os.pathconf -> long
10419 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10420 name: path_confname
10421
10422Return the configuration limit name for the file or directory path.
10423
10424If there is no limit, return -1.
10425On some platforms, path may also be specified as an open file descriptor.
10426 If this functionality is unavailable, using it raises an exception.
10427[clinic start generated code]*/
10428
Larry Hastings2f936352014-08-05 14:04:04 +100010429static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010430os_pathconf_impl(PyObject *module, path_t *path, int name)
10431/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010432{
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010434
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010436#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010437 if (path->fd != -1)
10438 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010439 else
10440#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010441 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 if (limit == -1 && errno != 0) {
10443 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010444 /* could be a path or name problem */
10445 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010446 else
Larry Hastings2f936352014-08-05 14:04:04 +100010447 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 }
Larry Hastings2f936352014-08-05 14:04:04 +100010449
10450 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010451}
Larry Hastings2f936352014-08-05 14:04:04 +100010452#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010453
10454#ifdef HAVE_CONFSTR
10455static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010456#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010458#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010459#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010461#endif
10462#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010464#endif
Fred Draked86ed291999-12-15 15:34:33 +000010465#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010467#endif
10468#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010470#endif
10471#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010473#endif
10474#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010476#endif
Fred Drakec9680921999-12-13 16:37:25 +000010477#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010479#endif
10480#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010482#endif
10483#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010485#endif
10486#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
Fred Draked86ed291999-12-15 15:34:33 +000010501#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010503#endif
Fred Drakec9680921999-12-13 16:37:25 +000010504#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
Fred Draked86ed291999-12-15 15:34:33 +000010507#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010509#endif
10510#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010512#endif
10513#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010515#endif
10516#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010518#endif
Fred Drakec9680921999-12-13 16:37:25 +000010519#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
10564#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
Fred Draked86ed291999-12-15 15:34:33 +000010567#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010569#endif
10570#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010572#endif
10573#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010575#endif
10576#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010578#endif
10579#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010581#endif
10582#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010584#endif
10585#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010587#endif
10588#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010590#endif
10591#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010593#endif
10594#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010596#endif
10597#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010599#endif
10600#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010602#endif
10603#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010605#endif
Fred Drakec9680921999-12-13 16:37:25 +000010606};
10607
10608static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010609conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010610{
10611 return conv_confname(arg, valuep, posix_constants_confstr,
10612 sizeof(posix_constants_confstr)
10613 / sizeof(struct constdef));
10614}
10615
Larry Hastings2f936352014-08-05 14:04:04 +100010616
10617/*[clinic input]
10618os.confstr
10619
10620 name: confstr_confname
10621 /
10622
10623Return a string-valued system configuration variable.
10624[clinic start generated code]*/
10625
Larry Hastings2f936352014-08-05 14:04:04 +100010626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010627os_confstr_impl(PyObject *module, int name)
10628/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010629{
10630 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010631 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010632 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010633
Victor Stinnercb043522010-09-10 23:49:04 +000010634 errno = 0;
10635 len = confstr(name, buffer, sizeof(buffer));
10636 if (len == 0) {
10637 if (errno) {
10638 posix_error();
10639 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010640 }
10641 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010642 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010643 }
10644 }
Victor Stinnercb043522010-09-10 23:49:04 +000010645
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010646 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010647 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010648 char *buf = PyMem_Malloc(len);
10649 if (buf == NULL)
10650 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010651 len2 = confstr(name, buf, len);
10652 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010653 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010654 PyMem_Free(buf);
10655 }
10656 else
10657 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010658 return result;
10659}
Larry Hastings2f936352014-08-05 14:04:04 +100010660#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010661
10662
10663#ifdef HAVE_SYSCONF
10664static struct constdef posix_constants_sysconf[] = {
10665#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010667#endif
10668#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010670#endif
10671#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010673#endif
10674#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010676#endif
10677#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
10680#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
10683#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010685#endif
10686#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
10689#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010691#endif
10692#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010694#endif
Fred Draked86ed291999-12-15 15:34:33 +000010695#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010697#endif
10698#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010700#endif
Fred Drakec9680921999-12-13 16:37:25 +000010701#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010703#endif
Fred Drakec9680921999-12-13 16:37:25 +000010704#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010706#endif
10707#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010709#endif
10710#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010712#endif
10713#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010715#endif
10716#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010718#endif
Fred Draked86ed291999-12-15 15:34:33 +000010719#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010721#endif
Fred Drakec9680921999-12-13 16:37:25 +000010722#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010724#endif
10725#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010727#endif
10728#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010730#endif
10731#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010733#endif
10734#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010736#endif
Fred Draked86ed291999-12-15 15:34:33 +000010737#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010739#endif
Fred Drakec9680921999-12-13 16:37:25 +000010740#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010742#endif
10743#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010745#endif
10746#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010748#endif
10749#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010751#endif
10752#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010754#endif
10755#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010757#endif
10758#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010760#endif
10761#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010763#endif
10764#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010766#endif
10767#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010769#endif
10770#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010772#endif
10773#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010775#endif
10776#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010778#endif
10779#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010781#endif
10782#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010784#endif
10785#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010787#endif
10788#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010790#endif
10791#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010793#endif
10794#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010795 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010796#endif
10797#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010798 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010799#endif
10800#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010802#endif
10803#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010805#endif
10806#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010808#endif
Fred Draked86ed291999-12-15 15:34:33 +000010809#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010811#endif
Fred Drakec9680921999-12-13 16:37:25 +000010812#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010814#endif
10815#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010817#endif
10818#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010820#endif
Fred Draked86ed291999-12-15 15:34:33 +000010821#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010823#endif
Fred Drakec9680921999-12-13 16:37:25 +000010824#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010826#endif
Fred Draked86ed291999-12-15 15:34:33 +000010827#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010829#endif
10830#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010832#endif
Fred Drakec9680921999-12-13 16:37:25 +000010833#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010835#endif
10836#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010838#endif
10839#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010841#endif
10842#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010844#endif
Fred Draked86ed291999-12-15 15:34:33 +000010845#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010847#endif
Fred Drakec9680921999-12-13 16:37:25 +000010848#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010850#endif
10851#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010853#endif
10854#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010856#endif
10857#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010859#endif
10860#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010862#endif
10863#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010865#endif
10866#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010868#endif
Fred Draked86ed291999-12-15 15:34:33 +000010869#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010871#endif
Fred Drakec9680921999-12-13 16:37:25 +000010872#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010874#endif
10875#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010877#endif
Fred Draked86ed291999-12-15 15:34:33 +000010878#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010880#endif
Fred Drakec9680921999-12-13 16:37:25 +000010881#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010883#endif
10884#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010886#endif
10887#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
10890#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
10893#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
Fred Draked86ed291999-12-15 15:34:33 +000010908#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010910#endif
10911#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010913#endif
Fred Drakec9680921999-12-13 16:37:25 +000010914#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010916#endif
10917#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010919#endif
10920#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010922#endif
10923#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010925#endif
10926#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010928#endif
10929#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010931#endif
10932#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010934#endif
10935#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
10938#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010940#endif
10941#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010943#endif
10944#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010946#endif
10947#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010949#endif
10950#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010952#endif
10953#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010955#endif
10956#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010958#endif
10959#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010961#endif
10962#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010964#endif
10965#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
10968#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010970#endif
10971#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010973#endif
10974#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010976#endif
10977#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010979#endif
10980#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010982#endif
10983#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010985#endif
10986#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010988#endif
10989#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010991#endif
10992#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010994#endif
10995#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010997#endif
10998#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011000#endif
11001#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011003#endif
11004#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011006#endif
11007#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011009#endif
11010#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011012#endif
11013#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011015#endif
11016#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011018#endif
Fred Draked86ed291999-12-15 15:34:33 +000011019#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011021#endif
Fred Drakec9680921999-12-13 16:37:25 +000011022#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011024#endif
11025#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011027#endif
11028#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011030#endif
11031#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011033#endif
11034#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011036#endif
11037#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011039#endif
11040#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011042#endif
11043#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011045#endif
11046#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011048#endif
11049#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011051#endif
11052#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011054#endif
11055#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011057#endif
11058#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011060#endif
11061#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011063#endif
11064#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011066#endif
11067#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011069#endif
11070#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011072#endif
11073#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011075#endif
11076#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011078#endif
11079#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011081#endif
11082#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011084#endif
11085#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011087#endif
11088#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011090#endif
11091#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011093#endif
11094#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011096#endif
11097#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011099#endif
11100#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011102#endif
11103#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
11106#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
11121#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
11124#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011126#endif
11127#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011129#endif
11130#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011132#endif
11133#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011135#endif
11136#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011138#endif
11139#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011141#endif
11142#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011144#endif
11145#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011147#endif
11148#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011150#endif
11151#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011153#endif
11154#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011156#endif
11157};
11158
11159static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011160conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011161{
11162 return conv_confname(arg, valuep, posix_constants_sysconf,
11163 sizeof(posix_constants_sysconf)
11164 / sizeof(struct constdef));
11165}
11166
Larry Hastings2f936352014-08-05 14:04:04 +100011167
11168/*[clinic input]
11169os.sysconf -> long
11170 name: sysconf_confname
11171 /
11172
11173Return an integer-valued system configuration variable.
11174[clinic start generated code]*/
11175
Larry Hastings2f936352014-08-05 14:04:04 +100011176static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011177os_sysconf_impl(PyObject *module, int name)
11178/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011179{
11180 long value;
11181
11182 errno = 0;
11183 value = sysconf(name);
11184 if (value == -1 && errno != 0)
11185 posix_error();
11186 return value;
11187}
11188#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011189
11190
Fred Drakebec628d1999-12-15 18:31:10 +000011191/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011192 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011193 * the exported dictionaries that are used to publish information about the
11194 * names available on the host platform.
11195 *
11196 * Sorting the table at runtime ensures that the table is properly ordered
11197 * when used, even for platforms we're not able to test on. It also makes
11198 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011199 */
Fred Drakebec628d1999-12-15 18:31:10 +000011200
11201static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011202cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011203{
11204 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011206 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011208
11209 return strcmp(c1->name, c2->name);
11210}
11211
11212static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011213setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011214 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011215{
Fred Drakebec628d1999-12-15 18:31:10 +000011216 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011217 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011218
11219 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11220 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011221 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011223
Barry Warsaw3155db32000-04-13 15:20:40 +000011224 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 PyObject *o = PyLong_FromLong(table[i].value);
11226 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11227 Py_XDECREF(o);
11228 Py_DECREF(d);
11229 return -1;
11230 }
11231 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011232 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011233 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011234}
11235
Fred Drakebec628d1999-12-15 18:31:10 +000011236/* Return -1 on failure, 0 on success. */
11237static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011238setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011239{
11240#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011241 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011242 sizeof(posix_constants_pathconf)
11243 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011244 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011245 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011246#endif
11247#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011248 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011249 sizeof(posix_constants_confstr)
11250 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011251 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011252 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011253#endif
11254#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011255 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011256 sizeof(posix_constants_sysconf)
11257 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011258 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011259 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011260#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011261 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011262}
Fred Draked86ed291999-12-15 15:34:33 +000011263
11264
Larry Hastings2f936352014-08-05 14:04:04 +100011265/*[clinic input]
11266os.abort
11267
11268Abort the interpreter immediately.
11269
11270This function 'dumps core' or otherwise fails in the hardest way possible
11271on the hosting operating system. This function never returns.
11272[clinic start generated code]*/
11273
Larry Hastings2f936352014-08-05 14:04:04 +100011274static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011275os_abort_impl(PyObject *module)
11276/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011277{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011278 abort();
11279 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011280#ifndef __clang__
11281 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11282 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11283 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011284 Py_FatalError("abort() called from Python code didn't abort!");
11285 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011286#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011287}
Fred Drakebec628d1999-12-15 18:31:10 +000011288
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011289#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011290/* Grab ShellExecute dynamically from shell32 */
11291static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011292static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11293 LPCWSTR, INT);
11294static int
11295check_ShellExecute()
11296{
11297 HINSTANCE hShell32;
11298
11299 /* only recheck */
11300 if (-1 == has_ShellExecute) {
11301 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011302 /* Security note: this call is not vulnerable to "DLL hijacking".
11303 SHELL32 is part of "KnownDLLs" and so Windows always load
11304 the system SHELL32.DLL, even if there is another SHELL32.DLL
11305 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011306 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011307 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011308 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11309 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011310 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011311 } else {
11312 has_ShellExecute = 0;
11313 }
Tony Roberts4860f012019-02-02 18:16:42 +010011314 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011315 }
11316 return has_ShellExecute;
11317}
11318
11319
Steve Dowercc16be82016-09-08 10:35:16 -070011320/*[clinic input]
11321os.startfile
11322 filepath: path_t
11323 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011324
Steve Dowercc16be82016-09-08 10:35:16 -070011325startfile(filepath [, operation])
11326
11327Start a file with its associated application.
11328
11329When "operation" is not specified or "open", this acts like
11330double-clicking the file in Explorer, or giving the file name as an
11331argument to the DOS "start" command: the file is opened with whatever
11332application (if any) its extension is associated.
11333When another "operation" is given, it specifies what should be done with
11334the file. A typical operation is "print".
11335
11336startfile returns as soon as the associated application is launched.
11337There is no option to wait for the application to close, and no way
11338to retrieve the application's exit status.
11339
11340The filepath is relative to the current directory. If you want to use
11341an absolute path, make sure the first character is not a slash ("/");
11342the underlying Win32 ShellExecute function doesn't work if it is.
11343[clinic start generated code]*/
11344
11345static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011346os_startfile_impl(PyObject *module, path_t *filepath,
11347 const Py_UNICODE *operation)
11348/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011349{
11350 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011351
11352 if(!check_ShellExecute()) {
11353 /* If the OS doesn't have ShellExecute, return a
11354 NotImplementedError. */
11355 return PyErr_Format(PyExc_NotImplementedError,
11356 "startfile not available on this platform");
11357 }
11358
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011360 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011361 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 Py_END_ALLOW_THREADS
11363
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011365 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011366 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 }
Steve Dowercc16be82016-09-08 10:35:16 -070011368 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011369}
Larry Hastings2f936352014-08-05 14:04:04 +100011370#endif /* MS_WINDOWS */
11371
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011372
Martin v. Löwis438b5342002-12-27 10:16:42 +000011373#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011374/*[clinic input]
11375os.getloadavg
11376
11377Return average recent system load information.
11378
11379Return the number of processes in the system run queue averaged over
11380the last 1, 5, and 15 minutes as a tuple of three floats.
11381Raises OSError if the load average was unobtainable.
11382[clinic start generated code]*/
11383
Larry Hastings2f936352014-08-05 14:04:04 +100011384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011385os_getloadavg_impl(PyObject *module)
11386/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011387{
11388 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011389 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011390 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11391 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011392 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011393 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011394}
Larry Hastings2f936352014-08-05 14:04:04 +100011395#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011396
Larry Hastings2f936352014-08-05 14:04:04 +100011397
11398/*[clinic input]
11399os.device_encoding
11400 fd: int
11401
11402Return a string describing the encoding of a terminal's file descriptor.
11403
11404The file descriptor must be attached to a terminal.
11405If the device is not a terminal, return None.
11406[clinic start generated code]*/
11407
Larry Hastings2f936352014-08-05 14:04:04 +100011408static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011409os_device_encoding_impl(PyObject *module, int fd)
11410/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011411{
Brett Cannonefb00c02012-02-29 18:31:31 -050011412 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011413}
11414
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011415
Larry Hastings2f936352014-08-05 14:04:04 +100011416#ifdef HAVE_SETRESUID
11417/*[clinic input]
11418os.setresuid
11419
11420 ruid: uid_t
11421 euid: uid_t
11422 suid: uid_t
11423 /
11424
11425Set the current process's real, effective, and saved user ids.
11426[clinic start generated code]*/
11427
Larry Hastings2f936352014-08-05 14:04:04 +100011428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011429os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11430/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011431{
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 if (setresuid(ruid, euid, suid) < 0)
11433 return posix_error();
11434 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011435}
Larry Hastings2f936352014-08-05 14:04:04 +100011436#endif /* HAVE_SETRESUID */
11437
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011438
11439#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011440/*[clinic input]
11441os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011442
Larry Hastings2f936352014-08-05 14:04:04 +100011443 rgid: gid_t
11444 egid: gid_t
11445 sgid: gid_t
11446 /
11447
11448Set the current process's real, effective, and saved group ids.
11449[clinic start generated code]*/
11450
Larry Hastings2f936352014-08-05 14:04:04 +100011451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011452os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11453/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011454{
Victor Stinner8c62be82010-05-06 00:08:46 +000011455 if (setresgid(rgid, egid, sgid) < 0)
11456 return posix_error();
11457 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011458}
Larry Hastings2f936352014-08-05 14:04:04 +100011459#endif /* HAVE_SETRESGID */
11460
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011461
11462#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011463/*[clinic input]
11464os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011465
Larry Hastings2f936352014-08-05 14:04:04 +100011466Return a tuple of the current process's real, effective, and saved user ids.
11467[clinic start generated code]*/
11468
Larry Hastings2f936352014-08-05 14:04:04 +100011469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011470os_getresuid_impl(PyObject *module)
11471/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011472{
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 if (getresuid(&ruid, &euid, &suid) < 0)
11475 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011476 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11477 _PyLong_FromUid(euid),
11478 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011479}
Larry Hastings2f936352014-08-05 14:04:04 +100011480#endif /* HAVE_GETRESUID */
11481
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011482
11483#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011484/*[clinic input]
11485os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011486
Larry Hastings2f936352014-08-05 14:04:04 +100011487Return a tuple of the current process's real, effective, and saved group ids.
11488[clinic start generated code]*/
11489
Larry Hastings2f936352014-08-05 14:04:04 +100011490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011491os_getresgid_impl(PyObject *module)
11492/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011493{
11494 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 if (getresgid(&rgid, &egid, &sgid) < 0)
11496 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011497 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11498 _PyLong_FromGid(egid),
11499 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011500}
Larry Hastings2f936352014-08-05 14:04:04 +100011501#endif /* HAVE_GETRESGID */
11502
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011503
Benjamin Peterson9428d532011-09-14 11:45:52 -040011504#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011505/*[clinic input]
11506os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011507
Larry Hastings2f936352014-08-05 14:04:04 +100011508 path: path_t(allow_fd=True)
11509 attribute: path_t
11510 *
11511 follow_symlinks: bool = True
11512
11513Return the value of extended attribute attribute on path.
11514
BNMetricsb9427072018-11-02 15:20:19 +000011515path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011516If follow_symlinks is False, and the last element of the path is a symbolic
11517 link, getxattr will examine the symbolic link itself instead of the file
11518 the link points to.
11519
11520[clinic start generated code]*/
11521
Larry Hastings2f936352014-08-05 14:04:04 +100011522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011523os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011524 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011525/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011526{
11527 Py_ssize_t i;
11528 PyObject *buffer = NULL;
11529
11530 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11531 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011532
Larry Hastings9cf065c2012-06-22 16:30:09 -070011533 for (i = 0; ; i++) {
11534 void *ptr;
11535 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011536 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011537 Py_ssize_t buffer_size = buffer_sizes[i];
11538 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011539 path_error(path);
11540 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011541 }
11542 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11543 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011544 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011545 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011546
Larry Hastings9cf065c2012-06-22 16:30:09 -070011547 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011548 if (path->fd >= 0)
11549 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011550 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011551 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011552 else
Larry Hastings2f936352014-08-05 14:04:04 +100011553 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011554 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011555
Larry Hastings9cf065c2012-06-22 16:30:09 -070011556 if (result < 0) {
11557 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011558 if (errno == ERANGE)
11559 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011560 path_error(path);
11561 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011562 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011563
Larry Hastings9cf065c2012-06-22 16:30:09 -070011564 if (result != buffer_size) {
11565 /* Can only shrink. */
11566 _PyBytes_Resize(&buffer, result);
11567 }
11568 break;
11569 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011570
Larry Hastings9cf065c2012-06-22 16:30:09 -070011571 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011572}
11573
Larry Hastings2f936352014-08-05 14:04:04 +100011574
11575/*[clinic input]
11576os.setxattr
11577
11578 path: path_t(allow_fd=True)
11579 attribute: path_t
11580 value: Py_buffer
11581 flags: int = 0
11582 *
11583 follow_symlinks: bool = True
11584
11585Set extended attribute attribute on path to value.
11586
BNMetricsb9427072018-11-02 15:20:19 +000011587path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011588If follow_symlinks is False, and the last element of the path is a symbolic
11589 link, setxattr will modify the symbolic link itself instead of the file
11590 the link points to.
11591
11592[clinic start generated code]*/
11593
Benjamin Peterson799bd802011-08-31 22:15:17 -040011594static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011595os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011596 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011597/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011598{
Larry Hastings2f936352014-08-05 14:04:04 +100011599 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011600
Larry Hastings2f936352014-08-05 14:04:04 +100011601 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011602 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011603
Benjamin Peterson799bd802011-08-31 22:15:17 -040011604 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011605 if (path->fd > -1)
11606 result = fsetxattr(path->fd, attribute->narrow,
11607 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011608 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011609 result = setxattr(path->narrow, attribute->narrow,
11610 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011611 else
Larry Hastings2f936352014-08-05 14:04:04 +100011612 result = lsetxattr(path->narrow, attribute->narrow,
11613 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011614 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011615
Larry Hastings9cf065c2012-06-22 16:30:09 -070011616 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011617 path_error(path);
11618 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011619 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011620
Larry Hastings2f936352014-08-05 14:04:04 +100011621 Py_RETURN_NONE;
11622}
11623
11624
11625/*[clinic input]
11626os.removexattr
11627
11628 path: path_t(allow_fd=True)
11629 attribute: path_t
11630 *
11631 follow_symlinks: bool = True
11632
11633Remove extended attribute attribute on path.
11634
BNMetricsb9427072018-11-02 15:20:19 +000011635path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011636If follow_symlinks is False, and the last element of the path is a symbolic
11637 link, removexattr will modify the symbolic link itself instead of the file
11638 the link points to.
11639
11640[clinic start generated code]*/
11641
Larry Hastings2f936352014-08-05 14:04:04 +100011642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011643os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011644 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011645/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011646{
11647 ssize_t result;
11648
11649 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11650 return NULL;
11651
11652 Py_BEGIN_ALLOW_THREADS;
11653 if (path->fd > -1)
11654 result = fremovexattr(path->fd, attribute->narrow);
11655 else if (follow_symlinks)
11656 result = removexattr(path->narrow, attribute->narrow);
11657 else
11658 result = lremovexattr(path->narrow, attribute->narrow);
11659 Py_END_ALLOW_THREADS;
11660
11661 if (result) {
11662 return path_error(path);
11663 }
11664
11665 Py_RETURN_NONE;
11666}
11667
11668
11669/*[clinic input]
11670os.listxattr
11671
11672 path: path_t(allow_fd=True, nullable=True) = None
11673 *
11674 follow_symlinks: bool = True
11675
11676Return a list of extended attributes on path.
11677
BNMetricsb9427072018-11-02 15:20:19 +000011678path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011679if path is None, listxattr will examine the current directory.
11680If follow_symlinks is False, and the last element of the path is a symbolic
11681 link, listxattr will examine the symbolic link itself instead of the file
11682 the link points to.
11683[clinic start generated code]*/
11684
Larry Hastings2f936352014-08-05 14:04:04 +100011685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011686os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011687/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011688{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011689 Py_ssize_t i;
11690 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011691 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011692 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011693
Larry Hastings2f936352014-08-05 14:04:04 +100011694 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011695 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011696
Larry Hastings2f936352014-08-05 14:04:04 +100011697 name = path->narrow ? path->narrow : ".";
11698
Larry Hastings9cf065c2012-06-22 16:30:09 -070011699 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011700 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011701 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011702 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011703 Py_ssize_t buffer_size = buffer_sizes[i];
11704 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011705 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011706 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011707 break;
11708 }
11709 buffer = PyMem_MALLOC(buffer_size);
11710 if (!buffer) {
11711 PyErr_NoMemory();
11712 break;
11713 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011714
Larry Hastings9cf065c2012-06-22 16:30:09 -070011715 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011716 if (path->fd > -1)
11717 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011718 else if (follow_symlinks)
11719 length = listxattr(name, buffer, buffer_size);
11720 else
11721 length = llistxattr(name, buffer, buffer_size);
11722 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011723
Larry Hastings9cf065c2012-06-22 16:30:09 -070011724 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011725 if (errno == ERANGE) {
11726 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011727 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011728 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011729 }
Larry Hastings2f936352014-08-05 14:04:04 +100011730 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011731 break;
11732 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011733
Larry Hastings9cf065c2012-06-22 16:30:09 -070011734 result = PyList_New(0);
11735 if (!result) {
11736 goto exit;
11737 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011738
Larry Hastings9cf065c2012-06-22 16:30:09 -070011739 end = buffer + length;
11740 for (trace = start = buffer; trace != end; trace++) {
11741 if (!*trace) {
11742 int error;
11743 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11744 trace - start);
11745 if (!attribute) {
11746 Py_DECREF(result);
11747 result = NULL;
11748 goto exit;
11749 }
11750 error = PyList_Append(result, attribute);
11751 Py_DECREF(attribute);
11752 if (error) {
11753 Py_DECREF(result);
11754 result = NULL;
11755 goto exit;
11756 }
11757 start = trace + 1;
11758 }
11759 }
11760 break;
11761 }
11762exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011763 if (buffer)
11764 PyMem_FREE(buffer);
11765 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011766}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011767#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011768
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011769
Larry Hastings2f936352014-08-05 14:04:04 +100011770/*[clinic input]
11771os.urandom
11772
11773 size: Py_ssize_t
11774 /
11775
11776Return a bytes object containing random bytes suitable for cryptographic use.
11777[clinic start generated code]*/
11778
Larry Hastings2f936352014-08-05 14:04:04 +100011779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011780os_urandom_impl(PyObject *module, Py_ssize_t size)
11781/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011782{
11783 PyObject *bytes;
11784 int result;
11785
Georg Brandl2fb477c2012-02-21 00:33:36 +010011786 if (size < 0)
11787 return PyErr_Format(PyExc_ValueError,
11788 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011789 bytes = PyBytes_FromStringAndSize(NULL, size);
11790 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011791 return NULL;
11792
Victor Stinnere66987e2016-09-06 16:33:52 -070011793 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011794 if (result == -1) {
11795 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011796 return NULL;
11797 }
Larry Hastings2f936352014-08-05 14:04:04 +100011798 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011799}
11800
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011801/* Terminal size querying */
11802
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011803static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011804
11805PyDoc_STRVAR(TerminalSize_docstring,
11806 "A tuple of (columns, lines) for holding terminal window size");
11807
11808static PyStructSequence_Field TerminalSize_fields[] = {
11809 {"columns", "width of the terminal window in characters"},
11810 {"lines", "height of the terminal window in characters"},
11811 {NULL, NULL}
11812};
11813
11814static PyStructSequence_Desc TerminalSize_desc = {
11815 "os.terminal_size",
11816 TerminalSize_docstring,
11817 TerminalSize_fields,
11818 2,
11819};
11820
11821#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011822/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011823PyDoc_STRVAR(termsize__doc__,
11824 "Return the size of the terminal window as (columns, lines).\n" \
11825 "\n" \
11826 "The optional argument fd (default standard output) specifies\n" \
11827 "which file descriptor should be queried.\n" \
11828 "\n" \
11829 "If the file descriptor is not connected to a terminal, an OSError\n" \
11830 "is thrown.\n" \
11831 "\n" \
11832 "This function will only be defined if an implementation is\n" \
11833 "available for this system.\n" \
11834 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011835 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011836 "normally be used, os.get_terminal_size is the low-level implementation.");
11837
11838static PyObject*
11839get_terminal_size(PyObject *self, PyObject *args)
11840{
11841 int columns, lines;
11842 PyObject *termsize;
11843
11844 int fd = fileno(stdout);
11845 /* Under some conditions stdout may not be connected and
11846 * fileno(stdout) may point to an invalid file descriptor. For example
11847 * GUI apps don't have valid standard streams by default.
11848 *
11849 * If this happens, and the optional fd argument is not present,
11850 * the ioctl below will fail returning EBADF. This is what we want.
11851 */
11852
11853 if (!PyArg_ParseTuple(args, "|i", &fd))
11854 return NULL;
11855
11856#ifdef TERMSIZE_USE_IOCTL
11857 {
11858 struct winsize w;
11859 if (ioctl(fd, TIOCGWINSZ, &w))
11860 return PyErr_SetFromErrno(PyExc_OSError);
11861 columns = w.ws_col;
11862 lines = w.ws_row;
11863 }
11864#endif /* TERMSIZE_USE_IOCTL */
11865
11866#ifdef TERMSIZE_USE_CONIO
11867 {
11868 DWORD nhandle;
11869 HANDLE handle;
11870 CONSOLE_SCREEN_BUFFER_INFO csbi;
11871 switch (fd) {
11872 case 0: nhandle = STD_INPUT_HANDLE;
11873 break;
11874 case 1: nhandle = STD_OUTPUT_HANDLE;
11875 break;
11876 case 2: nhandle = STD_ERROR_HANDLE;
11877 break;
11878 default:
11879 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11880 }
11881 handle = GetStdHandle(nhandle);
11882 if (handle == NULL)
11883 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11884 if (handle == INVALID_HANDLE_VALUE)
11885 return PyErr_SetFromWindowsErr(0);
11886
11887 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11888 return PyErr_SetFromWindowsErr(0);
11889
11890 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11891 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11892 }
11893#endif /* TERMSIZE_USE_CONIO */
11894
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011895 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011896 if (termsize == NULL)
11897 return NULL;
11898 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11899 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11900 if (PyErr_Occurred()) {
11901 Py_DECREF(termsize);
11902 return NULL;
11903 }
11904 return termsize;
11905}
11906#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11907
Larry Hastings2f936352014-08-05 14:04:04 +100011908
11909/*[clinic input]
11910os.cpu_count
11911
Charles-François Natali80d62e62015-08-13 20:37:08 +010011912Return the number of CPUs in the system; return None if indeterminable.
11913
11914This number is not equivalent to the number of CPUs the current process can
11915use. The number of usable CPUs can be obtained with
11916``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011917[clinic start generated code]*/
11918
Larry Hastings2f936352014-08-05 14:04:04 +100011919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011920os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011921/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011922{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011923 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011924#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011925 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11926 Need to fallback to Vista behavior if this call isn't present */
11927 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011928 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010011929 Py_BEGIN_ALLOW_THREADS
11930 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011931 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11932 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010011933 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011934 if (_GetMaximumProcessorCount != NULL) {
11935 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11936 }
11937 else {
11938 SYSTEM_INFO sysinfo;
11939 GetSystemInfo(&sysinfo);
11940 ncpu = sysinfo.dwNumberOfProcessors;
11941 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011942#elif defined(__hpux)
11943 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11944#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11945 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011946#elif defined(__DragonFly__) || \
11947 defined(__OpenBSD__) || \
11948 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011949 defined(__NetBSD__) || \
11950 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011951 int mib[2];
11952 size_t len = sizeof(ncpu);
11953 mib[0] = CTL_HW;
11954 mib[1] = HW_NCPU;
11955 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11956 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011957#endif
11958 if (ncpu >= 1)
11959 return PyLong_FromLong(ncpu);
11960 else
11961 Py_RETURN_NONE;
11962}
11963
Victor Stinnerdaf45552013-08-28 00:53:59 +020011964
Larry Hastings2f936352014-08-05 14:04:04 +100011965/*[clinic input]
11966os.get_inheritable -> bool
11967
11968 fd: int
11969 /
11970
11971Get the close-on-exe flag of the specified file descriptor.
11972[clinic start generated code]*/
11973
Larry Hastings2f936352014-08-05 14:04:04 +100011974static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011975os_get_inheritable_impl(PyObject *module, int fd)
11976/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011977{
Steve Dower8fc89802015-04-12 00:26:27 -040011978 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011979 _Py_BEGIN_SUPPRESS_IPH
11980 return_value = _Py_get_inheritable(fd);
11981 _Py_END_SUPPRESS_IPH
11982 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011983}
11984
11985
11986/*[clinic input]
11987os.set_inheritable
11988 fd: int
11989 inheritable: int
11990 /
11991
11992Set the inheritable flag of the specified file descriptor.
11993[clinic start generated code]*/
11994
Larry Hastings2f936352014-08-05 14:04:04 +100011995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011996os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11997/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011998{
Steve Dower8fc89802015-04-12 00:26:27 -040011999 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012000
Steve Dower8fc89802015-04-12 00:26:27 -040012001 _Py_BEGIN_SUPPRESS_IPH
12002 result = _Py_set_inheritable(fd, inheritable, NULL);
12003 _Py_END_SUPPRESS_IPH
12004 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012005 return NULL;
12006 Py_RETURN_NONE;
12007}
12008
12009
12010#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012011/*[clinic input]
12012os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012013 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012014 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012015
Larry Hastings2f936352014-08-05 14:04:04 +100012016Get the close-on-exe flag of the specified file descriptor.
12017[clinic start generated code]*/
12018
Larry Hastings2f936352014-08-05 14:04:04 +100012019static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012020os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012021/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012022{
12023 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012024
12025 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12026 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012027 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012028 }
12029
Larry Hastings2f936352014-08-05 14:04:04 +100012030 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012031}
12032
Victor Stinnerdaf45552013-08-28 00:53:59 +020012033
Larry Hastings2f936352014-08-05 14:04:04 +100012034/*[clinic input]
12035os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012036 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012037 inheritable: bool
12038 /
12039
12040Set the inheritable flag of the specified handle.
12041[clinic start generated code]*/
12042
Larry Hastings2f936352014-08-05 14:04:04 +100012043static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012044os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012045 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012046/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012047{
12048 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012049 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12050 PyErr_SetFromWindowsErr(0);
12051 return NULL;
12052 }
12053 Py_RETURN_NONE;
12054}
Larry Hastings2f936352014-08-05 14:04:04 +100012055#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012056
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012057#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012058/*[clinic input]
12059os.get_blocking -> bool
12060 fd: int
12061 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012062
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012063Get the blocking mode of the file descriptor.
12064
12065Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12066[clinic start generated code]*/
12067
12068static int
12069os_get_blocking_impl(PyObject *module, int fd)
12070/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012071{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012072 int blocking;
12073
Steve Dower8fc89802015-04-12 00:26:27 -040012074 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012075 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012076 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012077 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012078}
12079
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012080/*[clinic input]
12081os.set_blocking
12082 fd: int
12083 blocking: bool(accept={int})
12084 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012085
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012086Set the blocking mode of the specified file descriptor.
12087
12088Set the O_NONBLOCK flag if blocking is False,
12089clear the O_NONBLOCK flag otherwise.
12090[clinic start generated code]*/
12091
12092static PyObject *
12093os_set_blocking_impl(PyObject *module, int fd, int blocking)
12094/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012095{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012096 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012097
Steve Dower8fc89802015-04-12 00:26:27 -040012098 _Py_BEGIN_SUPPRESS_IPH
12099 result = _Py_set_blocking(fd, blocking);
12100 _Py_END_SUPPRESS_IPH
12101 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012102 return NULL;
12103 Py_RETURN_NONE;
12104}
12105#endif /* !MS_WINDOWS */
12106
12107
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012108/*[clinic input]
12109class os.DirEntry "DirEntry *" "&DirEntryType"
12110[clinic start generated code]*/
12111/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012112
12113typedef struct {
12114 PyObject_HEAD
12115 PyObject *name;
12116 PyObject *path;
12117 PyObject *stat;
12118 PyObject *lstat;
12119#ifdef MS_WINDOWS
12120 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012121 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012122 int got_file_index;
12123#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012124#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012125 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012126#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012127 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012128 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012129#endif
12130} DirEntry;
12131
12132static void
12133DirEntry_dealloc(DirEntry *entry)
12134{
12135 Py_XDECREF(entry->name);
12136 Py_XDECREF(entry->path);
12137 Py_XDECREF(entry->stat);
12138 Py_XDECREF(entry->lstat);
12139 Py_TYPE(entry)->tp_free((PyObject *)entry);
12140}
12141
12142/* Forward reference */
12143static int
12144DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12145
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012146/*[clinic input]
12147os.DirEntry.is_symlink -> bool
12148
12149Return True if the entry is a symbolic link; cached per entry.
12150[clinic start generated code]*/
12151
Victor Stinner6036e442015-03-08 01:58:04 +010012152static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012153os_DirEntry_is_symlink_impl(DirEntry *self)
12154/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012155{
12156#ifdef MS_WINDOWS
12157 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012158#elif defined(HAVE_DIRENT_D_TYPE)
12159 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012160 if (self->d_type != DT_UNKNOWN)
12161 return self->d_type == DT_LNK;
12162 else
12163 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012164#else
12165 /* POSIX without d_type */
12166 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012167#endif
12168}
12169
12170static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012171DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12172{
12173 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012174 STRUCT_STAT st;
12175 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012176
12177#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012178 if (!PyUnicode_FSDecoder(self->path, &ub))
12179 return NULL;
12180 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012181#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012182 if (!PyUnicode_FSConverter(self->path, &ub))
12183 return NULL;
12184 const char *path = PyBytes_AS_STRING(ub);
12185 if (self->dir_fd != DEFAULT_DIR_FD) {
12186#ifdef HAVE_FSTATAT
12187 result = fstatat(self->dir_fd, path, &st,
12188 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12189#else
12190 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12191 return NULL;
12192#endif /* HAVE_FSTATAT */
12193 }
12194 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012195#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012196 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012197 if (follow_symlinks)
12198 result = STAT(path, &st);
12199 else
12200 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012201 }
12202 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012203
12204 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012205 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012206
12207 return _pystat_fromstructstat(&st);
12208}
12209
12210static PyObject *
12211DirEntry_get_lstat(DirEntry *self)
12212{
12213 if (!self->lstat) {
12214#ifdef MS_WINDOWS
12215 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12216#else /* POSIX */
12217 self->lstat = DirEntry_fetch_stat(self, 0);
12218#endif
12219 }
12220 Py_XINCREF(self->lstat);
12221 return self->lstat;
12222}
12223
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012224/*[clinic input]
12225os.DirEntry.stat
12226 *
12227 follow_symlinks: bool = True
12228
12229Return stat_result object for the entry; cached per entry.
12230[clinic start generated code]*/
12231
Victor Stinner6036e442015-03-08 01:58:04 +010012232static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012233os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12234/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012235{
12236 if (!follow_symlinks)
12237 return DirEntry_get_lstat(self);
12238
12239 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012240 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012241 if (result == -1)
12242 return NULL;
12243 else if (result)
12244 self->stat = DirEntry_fetch_stat(self, 1);
12245 else
12246 self->stat = DirEntry_get_lstat(self);
12247 }
12248
12249 Py_XINCREF(self->stat);
12250 return self->stat;
12251}
12252
Victor Stinner6036e442015-03-08 01:58:04 +010012253/* Set exception and return -1 on error, 0 for False, 1 for True */
12254static int
12255DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12256{
12257 PyObject *stat = NULL;
12258 PyObject *st_mode = NULL;
12259 long mode;
12260 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012261#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012262 int is_symlink;
12263 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012264#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012265#ifdef MS_WINDOWS
12266 unsigned long dir_bits;
12267#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012268 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012269
12270#ifdef MS_WINDOWS
12271 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12272 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012273#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012274 is_symlink = self->d_type == DT_LNK;
12275 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12276#endif
12277
Victor Stinner35a97c02015-03-08 02:59:09 +010012278#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012279 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012280#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012281 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012282 if (!stat) {
12283 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12284 /* If file doesn't exist (anymore), then return False
12285 (i.e., say it's not a file/directory) */
12286 PyErr_Clear();
12287 return 0;
12288 }
12289 goto error;
12290 }
12291 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12292 if (!st_mode)
12293 goto error;
12294
12295 mode = PyLong_AsLong(st_mode);
12296 if (mode == -1 && PyErr_Occurred())
12297 goto error;
12298 Py_CLEAR(st_mode);
12299 Py_CLEAR(stat);
12300 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012301#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012302 }
12303 else if (is_symlink) {
12304 assert(mode_bits != S_IFLNK);
12305 result = 0;
12306 }
12307 else {
12308 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12309#ifdef MS_WINDOWS
12310 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12311 if (mode_bits == S_IFDIR)
12312 result = dir_bits != 0;
12313 else
12314 result = dir_bits == 0;
12315#else /* POSIX */
12316 if (mode_bits == S_IFDIR)
12317 result = self->d_type == DT_DIR;
12318 else
12319 result = self->d_type == DT_REG;
12320#endif
12321 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012322#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012323
12324 return result;
12325
12326error:
12327 Py_XDECREF(st_mode);
12328 Py_XDECREF(stat);
12329 return -1;
12330}
12331
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012332/*[clinic input]
12333os.DirEntry.is_dir -> bool
12334 *
12335 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012336
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012337Return True if the entry is a directory; cached per entry.
12338[clinic start generated code]*/
12339
12340static int
12341os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12342/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12343{
12344 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012345}
12346
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012347/*[clinic input]
12348os.DirEntry.is_file -> bool
12349 *
12350 follow_symlinks: bool = True
12351
12352Return True if the entry is a file; cached per entry.
12353[clinic start generated code]*/
12354
12355static int
12356os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12357/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012358{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012359 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012360}
12361
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012362/*[clinic input]
12363os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012364
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012365Return inode of the entry; cached per entry.
12366[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012367
12368static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012369os_DirEntry_inode_impl(DirEntry *self)
12370/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012371{
12372#ifdef MS_WINDOWS
12373 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012374 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012375 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012376 STRUCT_STAT stat;
12377 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012378
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012379 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012380 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012381 path = PyUnicode_AsUnicode(unicode);
12382 result = LSTAT(path, &stat);
12383 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012384
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012385 if (result != 0)
12386 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012387
12388 self->win32_file_index = stat.st_ino;
12389 self->got_file_index = 1;
12390 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012391 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12392 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012393#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012394 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12395 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012396#endif
12397}
12398
12399static PyObject *
12400DirEntry_repr(DirEntry *self)
12401{
12402 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12403}
12404
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012405/*[clinic input]
12406os.DirEntry.__fspath__
12407
12408Returns the path for the entry.
12409[clinic start generated code]*/
12410
Brett Cannon96881cd2016-06-10 14:37:21 -070012411static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012412os_DirEntry___fspath___impl(DirEntry *self)
12413/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012414{
12415 Py_INCREF(self->path);
12416 return self->path;
12417}
12418
Victor Stinner6036e442015-03-08 01:58:04 +010012419static PyMemberDef DirEntry_members[] = {
12420 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12421 "the entry's base filename, relative to scandir() \"path\" argument"},
12422 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12423 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12424 {NULL}
12425};
12426
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012427#include "clinic/posixmodule.c.h"
12428
Victor Stinner6036e442015-03-08 01:58:04 +010012429static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012430 OS_DIRENTRY_IS_DIR_METHODDEF
12431 OS_DIRENTRY_IS_FILE_METHODDEF
12432 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12433 OS_DIRENTRY_STAT_METHODDEF
12434 OS_DIRENTRY_INODE_METHODDEF
12435 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012436 {NULL}
12437};
12438
Benjamin Peterson5646de42015-04-12 17:56:34 -040012439static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012440 PyVarObject_HEAD_INIT(NULL, 0)
12441 MODNAME ".DirEntry", /* tp_name */
12442 sizeof(DirEntry), /* tp_basicsize */
12443 0, /* tp_itemsize */
12444 /* methods */
12445 (destructor)DirEntry_dealloc, /* tp_dealloc */
12446 0, /* tp_print */
12447 0, /* tp_getattr */
12448 0, /* tp_setattr */
12449 0, /* tp_compare */
12450 (reprfunc)DirEntry_repr, /* tp_repr */
12451 0, /* tp_as_number */
12452 0, /* tp_as_sequence */
12453 0, /* tp_as_mapping */
12454 0, /* tp_hash */
12455 0, /* tp_call */
12456 0, /* tp_str */
12457 0, /* tp_getattro */
12458 0, /* tp_setattro */
12459 0, /* tp_as_buffer */
12460 Py_TPFLAGS_DEFAULT, /* tp_flags */
12461 0, /* tp_doc */
12462 0, /* tp_traverse */
12463 0, /* tp_clear */
12464 0, /* tp_richcompare */
12465 0, /* tp_weaklistoffset */
12466 0, /* tp_iter */
12467 0, /* tp_iternext */
12468 DirEntry_methods, /* tp_methods */
12469 DirEntry_members, /* tp_members */
12470};
12471
12472#ifdef MS_WINDOWS
12473
12474static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012475join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012476{
12477 Py_ssize_t path_len;
12478 Py_ssize_t size;
12479 wchar_t *result;
12480 wchar_t ch;
12481
12482 if (!path_wide) { /* Default arg: "." */
12483 path_wide = L".";
12484 path_len = 1;
12485 }
12486 else {
12487 path_len = wcslen(path_wide);
12488 }
12489
12490 /* The +1's are for the path separator and the NUL */
12491 size = path_len + 1 + wcslen(filename) + 1;
12492 result = PyMem_New(wchar_t, size);
12493 if (!result) {
12494 PyErr_NoMemory();
12495 return NULL;
12496 }
12497 wcscpy(result, path_wide);
12498 if (path_len > 0) {
12499 ch = result[path_len - 1];
12500 if (ch != SEP && ch != ALTSEP && ch != L':')
12501 result[path_len++] = SEP;
12502 wcscpy(result + path_len, filename);
12503 }
12504 return result;
12505}
12506
12507static PyObject *
12508DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12509{
12510 DirEntry *entry;
12511 BY_HANDLE_FILE_INFORMATION file_info;
12512 ULONG reparse_tag;
12513 wchar_t *joined_path;
12514
12515 entry = PyObject_New(DirEntry, &DirEntryType);
12516 if (!entry)
12517 return NULL;
12518 entry->name = NULL;
12519 entry->path = NULL;
12520 entry->stat = NULL;
12521 entry->lstat = NULL;
12522 entry->got_file_index = 0;
12523
12524 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12525 if (!entry->name)
12526 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012527 if (path->narrow) {
12528 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12529 if (!entry->name)
12530 goto error;
12531 }
Victor Stinner6036e442015-03-08 01:58:04 +010012532
12533 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12534 if (!joined_path)
12535 goto error;
12536
12537 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12538 PyMem_Free(joined_path);
12539 if (!entry->path)
12540 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012541 if (path->narrow) {
12542 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12543 if (!entry->path)
12544 goto error;
12545 }
Victor Stinner6036e442015-03-08 01:58:04 +010012546
Steve Dowercc16be82016-09-08 10:35:16 -070012547 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012548 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12549
12550 return (PyObject *)entry;
12551
12552error:
12553 Py_DECREF(entry);
12554 return NULL;
12555}
12556
12557#else /* POSIX */
12558
12559static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012560join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012561{
12562 Py_ssize_t path_len;
12563 Py_ssize_t size;
12564 char *result;
12565
12566 if (!path_narrow) { /* Default arg: "." */
12567 path_narrow = ".";
12568 path_len = 1;
12569 }
12570 else {
12571 path_len = strlen(path_narrow);
12572 }
12573
12574 if (filename_len == -1)
12575 filename_len = strlen(filename);
12576
12577 /* The +1's are for the path separator and the NUL */
12578 size = path_len + 1 + filename_len + 1;
12579 result = PyMem_New(char, size);
12580 if (!result) {
12581 PyErr_NoMemory();
12582 return NULL;
12583 }
12584 strcpy(result, path_narrow);
12585 if (path_len > 0 && result[path_len - 1] != '/')
12586 result[path_len++] = '/';
12587 strcpy(result + path_len, filename);
12588 return result;
12589}
12590
12591static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012592DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012593 ino_t d_ino
12594#ifdef HAVE_DIRENT_D_TYPE
12595 , unsigned char d_type
12596#endif
12597 )
Victor Stinner6036e442015-03-08 01:58:04 +010012598{
12599 DirEntry *entry;
12600 char *joined_path;
12601
12602 entry = PyObject_New(DirEntry, &DirEntryType);
12603 if (!entry)
12604 return NULL;
12605 entry->name = NULL;
12606 entry->path = NULL;
12607 entry->stat = NULL;
12608 entry->lstat = NULL;
12609
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012610 if (path->fd != -1) {
12611 entry->dir_fd = path->fd;
12612 joined_path = NULL;
12613 }
12614 else {
12615 entry->dir_fd = DEFAULT_DIR_FD;
12616 joined_path = join_path_filename(path->narrow, name, name_len);
12617 if (!joined_path)
12618 goto error;
12619 }
Victor Stinner6036e442015-03-08 01:58:04 +010012620
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012621 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012622 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012623 if (joined_path)
12624 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012625 }
12626 else {
12627 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012628 if (joined_path)
12629 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012630 }
12631 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012632 if (!entry->name)
12633 goto error;
12634
12635 if (path->fd != -1) {
12636 entry->path = entry->name;
12637 Py_INCREF(entry->path);
12638 }
12639 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012640 goto error;
12641
Victor Stinner35a97c02015-03-08 02:59:09 +010012642#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012643 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012644#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012645 entry->d_ino = d_ino;
12646
12647 return (PyObject *)entry;
12648
12649error:
12650 Py_XDECREF(entry);
12651 return NULL;
12652}
12653
12654#endif
12655
12656
12657typedef struct {
12658 PyObject_HEAD
12659 path_t path;
12660#ifdef MS_WINDOWS
12661 HANDLE handle;
12662 WIN32_FIND_DATAW file_data;
12663 int first_time;
12664#else /* POSIX */
12665 DIR *dirp;
12666#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012667#ifdef HAVE_FDOPENDIR
12668 int fd;
12669#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012670} ScandirIterator;
12671
12672#ifdef MS_WINDOWS
12673
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012674static int
12675ScandirIterator_is_closed(ScandirIterator *iterator)
12676{
12677 return iterator->handle == INVALID_HANDLE_VALUE;
12678}
12679
Victor Stinner6036e442015-03-08 01:58:04 +010012680static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012681ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012682{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012683 HANDLE handle = iterator->handle;
12684
12685 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012686 return;
12687
Victor Stinner6036e442015-03-08 01:58:04 +010012688 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012689 Py_BEGIN_ALLOW_THREADS
12690 FindClose(handle);
12691 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012692}
12693
12694static PyObject *
12695ScandirIterator_iternext(ScandirIterator *iterator)
12696{
12697 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12698 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012699 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012700
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012701 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012702 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012703 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012704
12705 while (1) {
12706 if (!iterator->first_time) {
12707 Py_BEGIN_ALLOW_THREADS
12708 success = FindNextFileW(iterator->handle, file_data);
12709 Py_END_ALLOW_THREADS
12710 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012711 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012712 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012713 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012714 break;
12715 }
12716 }
12717 iterator->first_time = 0;
12718
12719 /* Skip over . and .. */
12720 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012721 wcscmp(file_data->cFileName, L"..") != 0) {
12722 entry = DirEntry_from_find_data(&iterator->path, file_data);
12723 if (!entry)
12724 break;
12725 return entry;
12726 }
Victor Stinner6036e442015-03-08 01:58:04 +010012727
12728 /* Loop till we get a non-dot directory or finish iterating */
12729 }
12730
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012731 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012732 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012733 return NULL;
12734}
12735
12736#else /* POSIX */
12737
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012738static int
12739ScandirIterator_is_closed(ScandirIterator *iterator)
12740{
12741 return !iterator->dirp;
12742}
12743
Victor Stinner6036e442015-03-08 01:58:04 +010012744static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012745ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012746{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012747 DIR *dirp = iterator->dirp;
12748
12749 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012750 return;
12751
Victor Stinner6036e442015-03-08 01:58:04 +010012752 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012753 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012754#ifdef HAVE_FDOPENDIR
12755 if (iterator->path.fd != -1)
12756 rewinddir(dirp);
12757#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012758 closedir(dirp);
12759 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012760 return;
12761}
12762
12763static PyObject *
12764ScandirIterator_iternext(ScandirIterator *iterator)
12765{
12766 struct dirent *direntp;
12767 Py_ssize_t name_len;
12768 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012769 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012770
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012771 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012772 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012773 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012774
12775 while (1) {
12776 errno = 0;
12777 Py_BEGIN_ALLOW_THREADS
12778 direntp = readdir(iterator->dirp);
12779 Py_END_ALLOW_THREADS
12780
12781 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012782 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012783 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012784 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012785 break;
12786 }
12787
12788 /* Skip over . and .. */
12789 name_len = NAMLEN(direntp);
12790 is_dot = direntp->d_name[0] == '.' &&
12791 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12792 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012793 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012794 name_len, direntp->d_ino
12795#ifdef HAVE_DIRENT_D_TYPE
12796 , direntp->d_type
12797#endif
12798 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012799 if (!entry)
12800 break;
12801 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012802 }
12803
12804 /* Loop till we get a non-dot directory or finish iterating */
12805 }
12806
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012807 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012808 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012809 return NULL;
12810}
12811
12812#endif
12813
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012814static PyObject *
12815ScandirIterator_close(ScandirIterator *self, PyObject *args)
12816{
12817 ScandirIterator_closedir(self);
12818 Py_RETURN_NONE;
12819}
12820
12821static PyObject *
12822ScandirIterator_enter(PyObject *self, PyObject *args)
12823{
12824 Py_INCREF(self);
12825 return self;
12826}
12827
12828static PyObject *
12829ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12830{
12831 ScandirIterator_closedir(self);
12832 Py_RETURN_NONE;
12833}
12834
Victor Stinner6036e442015-03-08 01:58:04 +010012835static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012836ScandirIterator_finalize(ScandirIterator *iterator)
12837{
12838 PyObject *error_type, *error_value, *error_traceback;
12839
12840 /* Save the current exception, if any. */
12841 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12842
12843 if (!ScandirIterator_is_closed(iterator)) {
12844 ScandirIterator_closedir(iterator);
12845
12846 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12847 "unclosed scandir iterator %R", iterator)) {
12848 /* Spurious errors can appear at shutdown */
12849 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12850 PyErr_WriteUnraisable((PyObject *) iterator);
12851 }
12852 }
12853 }
12854
Victor Stinner7bfa4092016-03-23 00:43:54 +010012855 path_cleanup(&iterator->path);
12856
12857 /* Restore the saved exception. */
12858 PyErr_Restore(error_type, error_value, error_traceback);
12859}
12860
12861static void
Victor Stinner6036e442015-03-08 01:58:04 +010012862ScandirIterator_dealloc(ScandirIterator *iterator)
12863{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012864 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12865 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012866
Victor Stinner6036e442015-03-08 01:58:04 +010012867 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12868}
12869
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012870static PyMethodDef ScandirIterator_methods[] = {
12871 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12872 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12873 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12874 {NULL}
12875};
12876
Benjamin Peterson5646de42015-04-12 17:56:34 -040012877static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012878 PyVarObject_HEAD_INIT(NULL, 0)
12879 MODNAME ".ScandirIterator", /* tp_name */
12880 sizeof(ScandirIterator), /* tp_basicsize */
12881 0, /* tp_itemsize */
12882 /* methods */
12883 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12884 0, /* tp_print */
12885 0, /* tp_getattr */
12886 0, /* tp_setattr */
12887 0, /* tp_compare */
12888 0, /* tp_repr */
12889 0, /* tp_as_number */
12890 0, /* tp_as_sequence */
12891 0, /* tp_as_mapping */
12892 0, /* tp_hash */
12893 0, /* tp_call */
12894 0, /* tp_str */
12895 0, /* tp_getattro */
12896 0, /* tp_setattro */
12897 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012898 Py_TPFLAGS_DEFAULT
12899 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012900 0, /* tp_doc */
12901 0, /* tp_traverse */
12902 0, /* tp_clear */
12903 0, /* tp_richcompare */
12904 0, /* tp_weaklistoffset */
12905 PyObject_SelfIter, /* tp_iter */
12906 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012907 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012908 0, /* tp_members */
12909 0, /* tp_getset */
12910 0, /* tp_base */
12911 0, /* tp_dict */
12912 0, /* tp_descr_get */
12913 0, /* tp_descr_set */
12914 0, /* tp_dictoffset */
12915 0, /* tp_init */
12916 0, /* tp_alloc */
12917 0, /* tp_new */
12918 0, /* tp_free */
12919 0, /* tp_is_gc */
12920 0, /* tp_bases */
12921 0, /* tp_mro */
12922 0, /* tp_cache */
12923 0, /* tp_subclasses */
12924 0, /* tp_weaklist */
12925 0, /* tp_del */
12926 0, /* tp_version_tag */
12927 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012928};
12929
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012930/*[clinic input]
12931os.scandir
12932
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012933 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012934
12935Return an iterator of DirEntry objects for given path.
12936
BNMetricsb9427072018-11-02 15:20:19 +000012937path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012938is bytes, the names of yielded DirEntry objects will also be bytes; in
12939all other circumstances they will be str.
12940
12941If path is None, uses the path='.'.
12942[clinic start generated code]*/
12943
Victor Stinner6036e442015-03-08 01:58:04 +010012944static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012945os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012946/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012947{
12948 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012949#ifdef MS_WINDOWS
12950 wchar_t *path_strW;
12951#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012952 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012953#ifdef HAVE_FDOPENDIR
12954 int fd = -1;
12955#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012956#endif
12957
12958 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12959 if (!iterator)
12960 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012961
12962#ifdef MS_WINDOWS
12963 iterator->handle = INVALID_HANDLE_VALUE;
12964#else
12965 iterator->dirp = NULL;
12966#endif
12967
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012968 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012969 /* Move the ownership to iterator->path */
12970 path->object = NULL;
12971 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012972
12973#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012974 iterator->first_time = 1;
12975
12976 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12977 if (!path_strW)
12978 goto error;
12979
12980 Py_BEGIN_ALLOW_THREADS
12981 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12982 Py_END_ALLOW_THREADS
12983
12984 PyMem_Free(path_strW);
12985
12986 if (iterator->handle == INVALID_HANDLE_VALUE) {
12987 path_error(&iterator->path);
12988 goto error;
12989 }
12990#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012991 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012992#ifdef HAVE_FDOPENDIR
12993 if (path->fd != -1) {
12994 /* closedir() closes the FD, so we duplicate it */
12995 fd = _Py_dup(path->fd);
12996 if (fd == -1)
12997 goto error;
12998
12999 Py_BEGIN_ALLOW_THREADS
13000 iterator->dirp = fdopendir(fd);
13001 Py_END_ALLOW_THREADS
13002 }
13003 else
13004#endif
13005 {
13006 if (iterator->path.narrow)
13007 path_str = iterator->path.narrow;
13008 else
13009 path_str = ".";
13010
13011 Py_BEGIN_ALLOW_THREADS
13012 iterator->dirp = opendir(path_str);
13013 Py_END_ALLOW_THREADS
13014 }
Victor Stinner6036e442015-03-08 01:58:04 +010013015
13016 if (!iterator->dirp) {
13017 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013018#ifdef HAVE_FDOPENDIR
13019 if (fd != -1) {
13020 Py_BEGIN_ALLOW_THREADS
13021 close(fd);
13022 Py_END_ALLOW_THREADS
13023 }
13024#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013025 goto error;
13026 }
13027#endif
13028
13029 return (PyObject *)iterator;
13030
13031error:
13032 Py_DECREF(iterator);
13033 return NULL;
13034}
13035
Ethan Furman410ef8e2016-06-04 12:06:26 -070013036/*
13037 Return the file system path representation of the object.
13038
13039 If the object is str or bytes, then allow it to pass through with
13040 an incremented refcount. If the object defines __fspath__(), then
13041 return the result of that method. All other types raise a TypeError.
13042*/
13043PyObject *
13044PyOS_FSPath(PyObject *path)
13045{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013046 /* For error message reasons, this function is manually inlined in
13047 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013048 _Py_IDENTIFIER(__fspath__);
13049 PyObject *func = NULL;
13050 PyObject *path_repr = NULL;
13051
13052 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13053 Py_INCREF(path);
13054 return path;
13055 }
13056
13057 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13058 if (NULL == func) {
13059 return PyErr_Format(PyExc_TypeError,
13060 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013061 "not %.200s",
13062 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013063 }
13064
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013065 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013066 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013067 if (NULL == path_repr) {
13068 return NULL;
13069 }
13070
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013071 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13072 PyErr_Format(PyExc_TypeError,
13073 "expected %.200s.__fspath__() to return str or bytes, "
13074 "not %.200s", Py_TYPE(path)->tp_name,
13075 Py_TYPE(path_repr)->tp_name);
13076 Py_DECREF(path_repr);
13077 return NULL;
13078 }
13079
Ethan Furman410ef8e2016-06-04 12:06:26 -070013080 return path_repr;
13081}
13082
13083/*[clinic input]
13084os.fspath
13085
13086 path: object
13087
13088Return the file system path representation of the object.
13089
Brett Cannonb4f43e92016-06-09 14:32:08 -070013090If the object is str or bytes, then allow it to pass through as-is. If the
13091object defines __fspath__(), then return the result of that method. All other
13092types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013093[clinic start generated code]*/
13094
13095static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013096os_fspath_impl(PyObject *module, PyObject *path)
13097/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013098{
13099 return PyOS_FSPath(path);
13100}
Victor Stinner6036e442015-03-08 01:58:04 +010013101
Victor Stinner9b1f4742016-09-06 16:18:52 -070013102#ifdef HAVE_GETRANDOM_SYSCALL
13103/*[clinic input]
13104os.getrandom
13105
13106 size: Py_ssize_t
13107 flags: int=0
13108
13109Obtain a series of random bytes.
13110[clinic start generated code]*/
13111
13112static PyObject *
13113os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13114/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13115{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013116 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013117 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013118
13119 if (size < 0) {
13120 errno = EINVAL;
13121 return posix_error();
13122 }
13123
Victor Stinnerec2319c2016-09-20 23:00:59 +020013124 bytes = PyBytes_FromStringAndSize(NULL, size);
13125 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013126 PyErr_NoMemory();
13127 return NULL;
13128 }
13129
13130 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013131 n = syscall(SYS_getrandom,
13132 PyBytes_AS_STRING(bytes),
13133 PyBytes_GET_SIZE(bytes),
13134 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013135 if (n < 0 && errno == EINTR) {
13136 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013137 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013138 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013139
13140 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013141 continue;
13142 }
13143 break;
13144 }
13145
13146 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013147 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013148 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013149 }
13150
Victor Stinnerec2319c2016-09-20 23:00:59 +020013151 if (n != size) {
13152 _PyBytes_Resize(&bytes, n);
13153 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013154
13155 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013156
13157error:
13158 Py_DECREF(bytes);
13159 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013160}
13161#endif /* HAVE_GETRANDOM_SYSCALL */
13162
Larry Hastings31826802013-10-19 00:09:25 -070013163
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013164static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013165
13166 OS_STAT_METHODDEF
13167 OS_ACCESS_METHODDEF
13168 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013169 OS_CHDIR_METHODDEF
13170 OS_CHFLAGS_METHODDEF
13171 OS_CHMOD_METHODDEF
13172 OS_FCHMOD_METHODDEF
13173 OS_LCHMOD_METHODDEF
13174 OS_CHOWN_METHODDEF
13175 OS_FCHOWN_METHODDEF
13176 OS_LCHOWN_METHODDEF
13177 OS_LCHFLAGS_METHODDEF
13178 OS_CHROOT_METHODDEF
13179 OS_CTERMID_METHODDEF
13180 OS_GETCWD_METHODDEF
13181 OS_GETCWDB_METHODDEF
13182 OS_LINK_METHODDEF
13183 OS_LISTDIR_METHODDEF
13184 OS_LSTAT_METHODDEF
13185 OS_MKDIR_METHODDEF
13186 OS_NICE_METHODDEF
13187 OS_GETPRIORITY_METHODDEF
13188 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013189 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013190 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013191 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013192 OS_RENAME_METHODDEF
13193 OS_REPLACE_METHODDEF
13194 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013195 OS_SYMLINK_METHODDEF
13196 OS_SYSTEM_METHODDEF
13197 OS_UMASK_METHODDEF
13198 OS_UNAME_METHODDEF
13199 OS_UNLINK_METHODDEF
13200 OS_REMOVE_METHODDEF
13201 OS_UTIME_METHODDEF
13202 OS_TIMES_METHODDEF
13203 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013204 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013205 OS_EXECV_METHODDEF
13206 OS_EXECVE_METHODDEF
13207 OS_SPAWNV_METHODDEF
13208 OS_SPAWNVE_METHODDEF
13209 OS_FORK1_METHODDEF
13210 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013211 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013212 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13213 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13214 OS_SCHED_GETPARAM_METHODDEF
13215 OS_SCHED_GETSCHEDULER_METHODDEF
13216 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13217 OS_SCHED_SETPARAM_METHODDEF
13218 OS_SCHED_SETSCHEDULER_METHODDEF
13219 OS_SCHED_YIELD_METHODDEF
13220 OS_SCHED_SETAFFINITY_METHODDEF
13221 OS_SCHED_GETAFFINITY_METHODDEF
13222 OS_OPENPTY_METHODDEF
13223 OS_FORKPTY_METHODDEF
13224 OS_GETEGID_METHODDEF
13225 OS_GETEUID_METHODDEF
13226 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013227#ifdef HAVE_GETGROUPLIST
13228 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13229#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013230 OS_GETGROUPS_METHODDEF
13231 OS_GETPID_METHODDEF
13232 OS_GETPGRP_METHODDEF
13233 OS_GETPPID_METHODDEF
13234 OS_GETUID_METHODDEF
13235 OS_GETLOGIN_METHODDEF
13236 OS_KILL_METHODDEF
13237 OS_KILLPG_METHODDEF
13238 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013239#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013240 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013241#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013242 OS_SETUID_METHODDEF
13243 OS_SETEUID_METHODDEF
13244 OS_SETREUID_METHODDEF
13245 OS_SETGID_METHODDEF
13246 OS_SETEGID_METHODDEF
13247 OS_SETREGID_METHODDEF
13248 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013249#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013250 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013251#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013252 OS_GETPGID_METHODDEF
13253 OS_SETPGRP_METHODDEF
13254 OS_WAIT_METHODDEF
13255 OS_WAIT3_METHODDEF
13256 OS_WAIT4_METHODDEF
13257 OS_WAITID_METHODDEF
13258 OS_WAITPID_METHODDEF
13259 OS_GETSID_METHODDEF
13260 OS_SETSID_METHODDEF
13261 OS_SETPGID_METHODDEF
13262 OS_TCGETPGRP_METHODDEF
13263 OS_TCSETPGRP_METHODDEF
13264 OS_OPEN_METHODDEF
13265 OS_CLOSE_METHODDEF
13266 OS_CLOSERANGE_METHODDEF
13267 OS_DEVICE_ENCODING_METHODDEF
13268 OS_DUP_METHODDEF
13269 OS_DUP2_METHODDEF
13270 OS_LOCKF_METHODDEF
13271 OS_LSEEK_METHODDEF
13272 OS_READ_METHODDEF
13273 OS_READV_METHODDEF
13274 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013275 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013276 OS_WRITE_METHODDEF
13277 OS_WRITEV_METHODDEF
13278 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013279 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013280#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013281 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013282 posix_sendfile__doc__},
13283#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013284 OS_FSTAT_METHODDEF
13285 OS_ISATTY_METHODDEF
13286 OS_PIPE_METHODDEF
13287 OS_PIPE2_METHODDEF
13288 OS_MKFIFO_METHODDEF
13289 OS_MKNOD_METHODDEF
13290 OS_MAJOR_METHODDEF
13291 OS_MINOR_METHODDEF
13292 OS_MAKEDEV_METHODDEF
13293 OS_FTRUNCATE_METHODDEF
13294 OS_TRUNCATE_METHODDEF
13295 OS_POSIX_FALLOCATE_METHODDEF
13296 OS_POSIX_FADVISE_METHODDEF
13297 OS_PUTENV_METHODDEF
13298 OS_UNSETENV_METHODDEF
13299 OS_STRERROR_METHODDEF
13300 OS_FCHDIR_METHODDEF
13301 OS_FSYNC_METHODDEF
13302 OS_SYNC_METHODDEF
13303 OS_FDATASYNC_METHODDEF
13304 OS_WCOREDUMP_METHODDEF
13305 OS_WIFCONTINUED_METHODDEF
13306 OS_WIFSTOPPED_METHODDEF
13307 OS_WIFSIGNALED_METHODDEF
13308 OS_WIFEXITED_METHODDEF
13309 OS_WEXITSTATUS_METHODDEF
13310 OS_WTERMSIG_METHODDEF
13311 OS_WSTOPSIG_METHODDEF
13312 OS_FSTATVFS_METHODDEF
13313 OS_STATVFS_METHODDEF
13314 OS_CONFSTR_METHODDEF
13315 OS_SYSCONF_METHODDEF
13316 OS_FPATHCONF_METHODDEF
13317 OS_PATHCONF_METHODDEF
13318 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013319 OS__GETFULLPATHNAME_METHODDEF
13320 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013321 OS__GETDISKUSAGE_METHODDEF
13322 OS__GETFINALPATHNAME_METHODDEF
13323 OS__GETVOLUMEPATHNAME_METHODDEF
13324 OS_GETLOADAVG_METHODDEF
13325 OS_URANDOM_METHODDEF
13326 OS_SETRESUID_METHODDEF
13327 OS_SETRESGID_METHODDEF
13328 OS_GETRESUID_METHODDEF
13329 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013330
Larry Hastings2f936352014-08-05 14:04:04 +100013331 OS_GETXATTR_METHODDEF
13332 OS_SETXATTR_METHODDEF
13333 OS_REMOVEXATTR_METHODDEF
13334 OS_LISTXATTR_METHODDEF
13335
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013336#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13337 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13338#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013339 OS_CPU_COUNT_METHODDEF
13340 OS_GET_INHERITABLE_METHODDEF
13341 OS_SET_INHERITABLE_METHODDEF
13342 OS_GET_HANDLE_INHERITABLE_METHODDEF
13343 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013344#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013345 OS_GET_BLOCKING_METHODDEF
13346 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013347#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013348 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013349 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013350 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000013351 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013352};
13353
13354
Brian Curtin52173d42010-12-02 18:29:18 +000013355#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013356static int
Brian Curtin52173d42010-12-02 18:29:18 +000013357enable_symlink()
13358{
13359 HANDLE tok;
13360 TOKEN_PRIVILEGES tok_priv;
13361 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000013362
13363 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013364 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013365
13366 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013367 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013368
13369 tok_priv.PrivilegeCount = 1;
13370 tok_priv.Privileges[0].Luid = luid;
13371 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
13372
13373 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
13374 sizeof(TOKEN_PRIVILEGES),
13375 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013376 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013377
Brian Curtin3b4499c2010-12-28 14:31:47 +000013378 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
13379 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000013380}
13381#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
13382
Barry Warsaw4a342091996-12-19 23:50:02 +000013383static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013384all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013385{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013386#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013387 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013388#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013389#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013390 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013391#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013392#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013393 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013394#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013395#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013396 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013397#endif
Fred Drakec9680921999-12-13 16:37:25 +000013398#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013399 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013400#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013401#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013402 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013403#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013404#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013405 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013406#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013407#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013408 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013409#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013410#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013411 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013412#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013413#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013414 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013415#endif
13416#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013417 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013418#endif
13419#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013420 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013421#endif
13422#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013423 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013424#endif
13425#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013426 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013427#endif
13428#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013429 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013430#endif
13431#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013432 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013433#endif
13434#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013435 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013436#endif
13437#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013438 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013439#endif
13440#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013441 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013442#endif
13443#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013444 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013445#endif
13446#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013447 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013448#endif
13449#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013450 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013451#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013452#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013453 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013454#endif
13455#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013456 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013457#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013458#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013459 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013460#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013461#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013462 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013463#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013464#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013465#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013466 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013467#endif
13468#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013469 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013470#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013471#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013472#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013473 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013474#endif
13475#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013476 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013477#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013478#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013479 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013480#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013481#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013482 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013483#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013484#ifdef O_TMPFILE
13485 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13486#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013487#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013488 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013489#endif
13490#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013491 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013492#endif
13493#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013494 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013495#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013496#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013497 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013498#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013499#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013500 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013501#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013502
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013503
Jesus Cea94363612012-06-22 18:32:07 +020013504#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013505 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013506#endif
13507#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013508 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013509#endif
13510
Tim Peters5aa91602002-01-30 05:46:57 +000013511/* MS Windows */
13512#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013513 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013514 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013515#endif
13516#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013517 /* Optimize for short life (keep in memory). */
13518 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013519 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013520#endif
13521#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013522 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013523 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013524#endif
13525#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013526 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013527 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013528#endif
13529#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013530 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013531 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013532#endif
13533
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013534/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013535#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013536 /* Send a SIGIO signal whenever input or output
13537 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013538 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013539#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013540#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013541 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013542 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013543#endif
13544#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013545 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013546 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013547#endif
13548#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013549 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013550 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013551#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013552#ifdef O_NOLINKS
13553 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013554 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013555#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013556#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013557 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013558 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013559#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013560
Victor Stinner8c62be82010-05-06 00:08:46 +000013561 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013562#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013563 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013564#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013565#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013566 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013567#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013568#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013569 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013570#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013571#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013572 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013573#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013574#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013575 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013576#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013577#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013578 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013579#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013580#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013581 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013582#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013583#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013584 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013585#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013586#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013587 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013588#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013589#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013590 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013591#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013592#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013593 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013594#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013595#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013596 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013597#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013598#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013599 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013600#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013601#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013602 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013603#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013604#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013605 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013606#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013607#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013608 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013609#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013610#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013611 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013612#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013613
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013614 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013615#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013616 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013617#endif /* ST_RDONLY */
13618#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013619 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013620#endif /* ST_NOSUID */
13621
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013622 /* GNU extensions */
13623#ifdef ST_NODEV
13624 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13625#endif /* ST_NODEV */
13626#ifdef ST_NOEXEC
13627 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13628#endif /* ST_NOEXEC */
13629#ifdef ST_SYNCHRONOUS
13630 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13631#endif /* ST_SYNCHRONOUS */
13632#ifdef ST_MANDLOCK
13633 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13634#endif /* ST_MANDLOCK */
13635#ifdef ST_WRITE
13636 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13637#endif /* ST_WRITE */
13638#ifdef ST_APPEND
13639 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13640#endif /* ST_APPEND */
13641#ifdef ST_NOATIME
13642 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13643#endif /* ST_NOATIME */
13644#ifdef ST_NODIRATIME
13645 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13646#endif /* ST_NODIRATIME */
13647#ifdef ST_RELATIME
13648 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13649#endif /* ST_RELATIME */
13650
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013651 /* FreeBSD sendfile() constants */
13652#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013653 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013654#endif
13655#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013656 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013657#endif
13658#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013659 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013660#endif
13661
Ross Lagerwall7807c352011-03-17 20:20:30 +020013662 /* constants for posix_fadvise */
13663#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013664 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013665#endif
13666#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013667 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013668#endif
13669#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013670 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013671#endif
13672#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013673 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013674#endif
13675#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013676 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013677#endif
13678#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013679 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013680#endif
13681
13682 /* constants for waitid */
13683#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013684 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13685 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13686 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013687#endif
13688#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013689 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013690#endif
13691#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013692 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013693#endif
13694#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013695 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013696#endif
13697#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013698 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013699#endif
13700#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013701 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013702#endif
13703#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013704 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013705#endif
13706#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013707 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013708#endif
13709
13710 /* constants for lockf */
13711#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013712 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013713#endif
13714#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013715 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013716#endif
13717#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013718 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013719#endif
13720#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013721 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013722#endif
13723
Pablo Galindo4defba32018-01-27 16:16:37 +000013724#ifdef RWF_DSYNC
13725 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13726#endif
13727#ifdef RWF_HIPRI
13728 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13729#endif
13730#ifdef RWF_SYNC
13731 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13732#endif
13733#ifdef RWF_NOWAIT
13734 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13735#endif
13736
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013737/* constants for posix_spawn */
13738#ifdef HAVE_POSIX_SPAWN
13739 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13740 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13741 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13742#endif
13743
Guido van Rossum246bc171999-02-01 23:54:31 +000013744#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013745 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13746 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13747 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13748 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13749 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013750#endif
13751
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013752#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013753#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013754 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013755#endif
13756#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013757 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013758#endif
13759#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013760 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013761#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013762#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013763 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013764#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013765#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013766 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013767#endif
13768#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013769 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013770#endif
13771#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013772 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013773#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013774#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013775 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013776#endif
13777#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013778 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013779#endif
13780#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013781 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013782#endif
13783#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013784 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013785#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013786#endif
13787
Benjamin Peterson9428d532011-09-14 11:45:52 -040013788#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013789 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13790 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13791 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013792#endif
13793
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013794#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013795 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013796#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013797#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013798 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013799#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013800#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013801 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013802#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013803#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013804 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013805#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013806#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013807 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013808#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013809#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013810 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013811#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013812#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013813 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013814#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013815#if HAVE_DECL_RTLD_MEMBER
13816 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13817#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013818
Victor Stinner9b1f4742016-09-06 16:18:52 -070013819#ifdef HAVE_GETRANDOM_SYSCALL
13820 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13821 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13822#endif
13823
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013824#if defined(__APPLE__)
13825 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13826#endif
13827
Victor Stinner8c62be82010-05-06 00:08:46 +000013828 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013829}
13830
13831
Martin v. Löwis1a214512008-06-11 05:26:20 +000013832static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013833 PyModuleDef_HEAD_INIT,
13834 MODNAME,
13835 posix__doc__,
13836 -1,
13837 posix_methods,
13838 NULL,
13839 NULL,
13840 NULL,
13841 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013842};
13843
13844
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013845static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013846
13847#ifdef HAVE_FACCESSAT
13848 "HAVE_FACCESSAT",
13849#endif
13850
13851#ifdef HAVE_FCHDIR
13852 "HAVE_FCHDIR",
13853#endif
13854
13855#ifdef HAVE_FCHMOD
13856 "HAVE_FCHMOD",
13857#endif
13858
13859#ifdef HAVE_FCHMODAT
13860 "HAVE_FCHMODAT",
13861#endif
13862
13863#ifdef HAVE_FCHOWN
13864 "HAVE_FCHOWN",
13865#endif
13866
Larry Hastings00964ed2013-08-12 13:49:30 -040013867#ifdef HAVE_FCHOWNAT
13868 "HAVE_FCHOWNAT",
13869#endif
13870
Larry Hastings9cf065c2012-06-22 16:30:09 -070013871#ifdef HAVE_FEXECVE
13872 "HAVE_FEXECVE",
13873#endif
13874
13875#ifdef HAVE_FDOPENDIR
13876 "HAVE_FDOPENDIR",
13877#endif
13878
Georg Brandl306336b2012-06-24 12:55:33 +020013879#ifdef HAVE_FPATHCONF
13880 "HAVE_FPATHCONF",
13881#endif
13882
Larry Hastings9cf065c2012-06-22 16:30:09 -070013883#ifdef HAVE_FSTATAT
13884 "HAVE_FSTATAT",
13885#endif
13886
13887#ifdef HAVE_FSTATVFS
13888 "HAVE_FSTATVFS",
13889#endif
13890
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013891#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013892 "HAVE_FTRUNCATE",
13893#endif
13894
Larry Hastings9cf065c2012-06-22 16:30:09 -070013895#ifdef HAVE_FUTIMENS
13896 "HAVE_FUTIMENS",
13897#endif
13898
13899#ifdef HAVE_FUTIMES
13900 "HAVE_FUTIMES",
13901#endif
13902
13903#ifdef HAVE_FUTIMESAT
13904 "HAVE_FUTIMESAT",
13905#endif
13906
13907#ifdef HAVE_LINKAT
13908 "HAVE_LINKAT",
13909#endif
13910
13911#ifdef HAVE_LCHFLAGS
13912 "HAVE_LCHFLAGS",
13913#endif
13914
13915#ifdef HAVE_LCHMOD
13916 "HAVE_LCHMOD",
13917#endif
13918
13919#ifdef HAVE_LCHOWN
13920 "HAVE_LCHOWN",
13921#endif
13922
13923#ifdef HAVE_LSTAT
13924 "HAVE_LSTAT",
13925#endif
13926
13927#ifdef HAVE_LUTIMES
13928 "HAVE_LUTIMES",
13929#endif
13930
13931#ifdef HAVE_MKDIRAT
13932 "HAVE_MKDIRAT",
13933#endif
13934
13935#ifdef HAVE_MKFIFOAT
13936 "HAVE_MKFIFOAT",
13937#endif
13938
13939#ifdef HAVE_MKNODAT
13940 "HAVE_MKNODAT",
13941#endif
13942
13943#ifdef HAVE_OPENAT
13944 "HAVE_OPENAT",
13945#endif
13946
13947#ifdef HAVE_READLINKAT
13948 "HAVE_READLINKAT",
13949#endif
13950
13951#ifdef HAVE_RENAMEAT
13952 "HAVE_RENAMEAT",
13953#endif
13954
13955#ifdef HAVE_SYMLINKAT
13956 "HAVE_SYMLINKAT",
13957#endif
13958
13959#ifdef HAVE_UNLINKAT
13960 "HAVE_UNLINKAT",
13961#endif
13962
13963#ifdef HAVE_UTIMENSAT
13964 "HAVE_UTIMENSAT",
13965#endif
13966
13967#ifdef MS_WINDOWS
13968 "MS_WINDOWS",
13969#endif
13970
13971 NULL
13972};
13973
13974
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013975PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013976INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013977{
Victor Stinner8c62be82010-05-06 00:08:46 +000013978 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013979 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013980 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013981
Brian Curtin52173d42010-12-02 18:29:18 +000013982#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013983 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013984#endif
13985
Victor Stinner8c62be82010-05-06 00:08:46 +000013986 m = PyModule_Create(&posixmodule);
13987 if (m == NULL)
13988 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013989
Victor Stinner8c62be82010-05-06 00:08:46 +000013990 /* Initialize environ dictionary */
13991 v = convertenviron();
13992 Py_XINCREF(v);
13993 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13994 return NULL;
13995 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013996
Victor Stinner8c62be82010-05-06 00:08:46 +000013997 if (all_ins(m))
13998 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013999
Victor Stinner8c62be82010-05-06 00:08:46 +000014000 if (setup_confname_tables(m))
14001 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014002
Victor Stinner8c62be82010-05-06 00:08:46 +000014003 Py_INCREF(PyExc_OSError);
14004 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014005
Guido van Rossumb3d39562000-01-31 18:41:26 +000014006#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014007 if (posix_putenv_garbage == NULL)
14008 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014009#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014010
Victor Stinner8c62be82010-05-06 00:08:46 +000014011 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014012#if defined(HAVE_WAITID) && !defined(__APPLE__)
14013 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014014 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14015 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014016 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014017 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014018#endif
14019
Christian Heimes25827622013-10-12 01:27:08 +020014020 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014021 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14022 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14023 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014024 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14025 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014026 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014027 }
14028 structseq_new = StatResultType->tp_new;
14029 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014030
Christian Heimes25827622013-10-12 01:27:08 +020014031 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014032 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14033 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014034 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014035 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014036#ifdef NEED_TICKS_PER_SECOND
14037# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014038 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014039# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014040 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014041# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014042 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014043# endif
14044#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014045
William Orr81574b82018-10-01 22:19:56 -070014046#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014047 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014048 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14049 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014050 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014051 }
14052 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014053#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014054
14055 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014056 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14057 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014058 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014059 }
Victor Stinner6036e442015-03-08 01:58:04 +010014060
14061 /* initialize scandir types */
14062 if (PyType_Ready(&ScandirIteratorType) < 0)
14063 return NULL;
14064 if (PyType_Ready(&DirEntryType) < 0)
14065 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014066 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014067#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014068 Py_INCREF((PyObject*) WaitidResultType);
14069 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014070#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014071 Py_INCREF((PyObject*) StatResultType);
14072 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14073 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014074 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014075 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014076
14077#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014078 Py_INCREF(SchedParamType);
14079 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014080#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014081
Larry Hastings605a62d2012-06-24 04:33:36 -070014082 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014083 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14084 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014085 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014086 }
14087 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014088
14089 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014090 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14091 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014092 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014093 }
14094 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014095
Thomas Wouters477c8d52006-05-27 19:21:47 +000014096#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014097 /*
14098 * Step 2 of weak-linking support on Mac OS X.
14099 *
14100 * The code below removes functions that are not available on the
14101 * currently active platform.
14102 *
14103 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014104 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014105 * OSX 10.4.
14106 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014107#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014108 if (fstatvfs == NULL) {
14109 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14110 return NULL;
14111 }
14112 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014113#endif /* HAVE_FSTATVFS */
14114
14115#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014116 if (statvfs == NULL) {
14117 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14118 return NULL;
14119 }
14120 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014121#endif /* HAVE_STATVFS */
14122
14123# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014124 if (lchown == NULL) {
14125 if (PyObject_DelAttrString(m, "lchown") == -1) {
14126 return NULL;
14127 }
14128 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014129#endif /* HAVE_LCHOWN */
14130
14131
14132#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014133
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014134 Py_INCREF(TerminalSizeType);
14135 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014136
Larry Hastings6fe20b32012-04-19 15:07:49 -070014137 billion = PyLong_FromLong(1000000000);
14138 if (!billion)
14139 return NULL;
14140
Larry Hastings9cf065c2012-06-22 16:30:09 -070014141 /* suppress "function not used" warnings */
14142 {
14143 int ignored;
14144 fd_specified("", -1);
14145 follow_symlinks_specified("", 1);
14146 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14147 dir_fd_converter(Py_None, &ignored);
14148 dir_fd_unavailable(Py_None, &ignored);
14149 }
14150
14151 /*
14152 * provide list of locally available functions
14153 * so os.py can populate support_* lists
14154 */
14155 list = PyList_New(0);
14156 if (!list)
14157 return NULL;
14158 for (trace = have_functions; *trace; trace++) {
14159 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14160 if (!unicode)
14161 return NULL;
14162 if (PyList_Append(list, unicode))
14163 return NULL;
14164 Py_DECREF(unicode);
14165 }
14166 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014167
14168 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014169 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014170
14171 initialized = 1;
14172
Victor Stinner8c62be82010-05-06 00:08:46 +000014173 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014174}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014175
14176#ifdef __cplusplus
14177}
14178#endif