blob: 05afe9efa188beea385185e64783231d1bb58ab1 [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. Kuchling8d2f2b2d2000-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. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007200}
7201#endif /* HAVE_SETEUID */
7202
Larry Hastings2f936352014-08-05 14:04:04 +10007203
Andrew M. Kuchling8d2f2b2d2000-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. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007221}
7222#endif /* HAVE_SETEGID */
7223
Larry Hastings2f936352014-08-05 14:04:04 +10007224
Andrew M. Kuchling8d2f2b2d2000-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. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007245}
7246#endif /* HAVE_SETREUID */
7247
Larry Hastings2f936352014-08-05 14:04:04 +10007248
Andrew M. Kuchling8d2f2b2d2000-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. Kuchling8d2f2b2d2000-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 */
9840 PyErr_Clear();
9841 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009842 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009843}
Larry Hastings2f936352014-08-05 14:04:04 +10009844#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009845
Larry Hastings2f936352014-08-05 14:04:04 +10009846
9847/*[clinic input]
9848os.strerror
9849
9850 code: int
9851 /
9852
9853Translate an error code to a message string.
9854[clinic start generated code]*/
9855
Larry Hastings2f936352014-08-05 14:04:04 +10009856static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009857os_strerror_impl(PyObject *module, int code)
9858/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009859{
9860 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 if (message == NULL) {
9862 PyErr_SetString(PyExc_ValueError,
9863 "strerror() argument out of range");
9864 return NULL;
9865 }
Victor Stinner1b579672011-12-17 05:47:23 +01009866 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009867}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009868
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009869
Guido van Rossumc9641791998-08-04 15:26:23 +00009870#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009871#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009872/*[clinic input]
9873os.WCOREDUMP -> bool
9874
9875 status: int
9876 /
9877
9878Return True if the process returning status was dumped to a core file.
9879[clinic start generated code]*/
9880
Larry Hastings2f936352014-08-05 14:04:04 +10009881static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009882os_WCOREDUMP_impl(PyObject *module, int status)
9883/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009884{
9885 WAIT_TYPE wait_status;
9886 WAIT_STATUS_INT(wait_status) = status;
9887 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009888}
9889#endif /* WCOREDUMP */
9890
Larry Hastings2f936352014-08-05 14:04:04 +10009891
Fred Drake106c1a02002-04-23 15:58:02 +00009892#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009893/*[clinic input]
9894os.WIFCONTINUED -> bool
9895
9896 status: int
9897
9898Return True if a particular process was continued from a job control stop.
9899
9900Return True if the process returning status was continued from a
9901job control stop.
9902[clinic start generated code]*/
9903
Larry Hastings2f936352014-08-05 14:04:04 +10009904static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009905os_WIFCONTINUED_impl(PyObject *module, int status)
9906/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009907{
9908 WAIT_TYPE wait_status;
9909 WAIT_STATUS_INT(wait_status) = status;
9910 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009911}
9912#endif /* WIFCONTINUED */
9913
Larry Hastings2f936352014-08-05 14:04:04 +10009914
Guido van Rossumc9641791998-08-04 15:26:23 +00009915#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009916/*[clinic input]
9917os.WIFSTOPPED -> bool
9918
9919 status: int
9920
9921Return True if the process returning status was stopped.
9922[clinic start generated code]*/
9923
Larry Hastings2f936352014-08-05 14:04:04 +10009924static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009925os_WIFSTOPPED_impl(PyObject *module, int status)
9926/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009927{
9928 WAIT_TYPE wait_status;
9929 WAIT_STATUS_INT(wait_status) = status;
9930 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009931}
9932#endif /* WIFSTOPPED */
9933
Larry Hastings2f936352014-08-05 14:04:04 +10009934
Guido van Rossumc9641791998-08-04 15:26:23 +00009935#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009936/*[clinic input]
9937os.WIFSIGNALED -> bool
9938
9939 status: int
9940
9941Return True if the process returning status was terminated by a signal.
9942[clinic start generated code]*/
9943
Larry Hastings2f936352014-08-05 14:04:04 +10009944static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009945os_WIFSIGNALED_impl(PyObject *module, int status)
9946/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009947{
9948 WAIT_TYPE wait_status;
9949 WAIT_STATUS_INT(wait_status) = status;
9950 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009951}
9952#endif /* WIFSIGNALED */
9953
Larry Hastings2f936352014-08-05 14:04:04 +10009954
Guido van Rossumc9641791998-08-04 15:26:23 +00009955#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009956/*[clinic input]
9957os.WIFEXITED -> bool
9958
9959 status: int
9960
9961Return True if the process returning status exited via the exit() system call.
9962[clinic start generated code]*/
9963
Larry Hastings2f936352014-08-05 14:04:04 +10009964static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009965os_WIFEXITED_impl(PyObject *module, int status)
9966/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009967{
9968 WAIT_TYPE wait_status;
9969 WAIT_STATUS_INT(wait_status) = status;
9970 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009971}
9972#endif /* WIFEXITED */
9973
Larry Hastings2f936352014-08-05 14:04:04 +10009974
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009975#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009976/*[clinic input]
9977os.WEXITSTATUS -> int
9978
9979 status: int
9980
9981Return the process return code from status.
9982[clinic start generated code]*/
9983
Larry Hastings2f936352014-08-05 14:04:04 +10009984static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009985os_WEXITSTATUS_impl(PyObject *module, int status)
9986/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009987{
9988 WAIT_TYPE wait_status;
9989 WAIT_STATUS_INT(wait_status) = status;
9990 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009991}
9992#endif /* WEXITSTATUS */
9993
Larry Hastings2f936352014-08-05 14:04:04 +10009994
Guido van Rossumc9641791998-08-04 15:26:23 +00009995#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009996/*[clinic input]
9997os.WTERMSIG -> int
9998
9999 status: int
10000
10001Return the signal that terminated the process that provided the status value.
10002[clinic start generated code]*/
10003
Larry Hastings2f936352014-08-05 14:04:04 +100010004static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010005os_WTERMSIG_impl(PyObject *module, int status)
10006/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010007{
10008 WAIT_TYPE wait_status;
10009 WAIT_STATUS_INT(wait_status) = status;
10010 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010011}
10012#endif /* WTERMSIG */
10013
Larry Hastings2f936352014-08-05 14:04:04 +100010014
Guido van Rossumc9641791998-08-04 15:26:23 +000010015#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010016/*[clinic input]
10017os.WSTOPSIG -> int
10018
10019 status: int
10020
10021Return the signal that stopped the process that provided the status value.
10022[clinic start generated code]*/
10023
Larry Hastings2f936352014-08-05 14:04:04 +100010024static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010025os_WSTOPSIG_impl(PyObject *module, int status)
10026/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010027{
10028 WAIT_TYPE wait_status;
10029 WAIT_STATUS_INT(wait_status) = status;
10030 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010031}
10032#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010033#endif /* HAVE_SYS_WAIT_H */
10034
10035
Thomas Wouters477c8d52006-05-27 19:21:47 +000010036#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010037#ifdef _SCO_DS
10038/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10039 needed definitions in sys/statvfs.h */
10040#define _SVID3
10041#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010042#include <sys/statvfs.h>
10043
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010044static PyObject*
10045_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010046 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 if (v == NULL)
10048 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010049
10050#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10052 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10053 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10054 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10055 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10056 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10057 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10058 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10059 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10060 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010061#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10063 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10064 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010065 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010067 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010069 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010071 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010073 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010075 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10077 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010078#endif
Michael Felt502d5512018-01-05 13:01:58 +010010079/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10080 * (issue #32390). */
10081#if defined(_AIX) && defined(_ALL_SOURCE)
10082 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10083#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010084 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010085#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010086 if (PyErr_Occurred()) {
10087 Py_DECREF(v);
10088 return NULL;
10089 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010090
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010092}
10093
Larry Hastings2f936352014-08-05 14:04:04 +100010094
10095/*[clinic input]
10096os.fstatvfs
10097 fd: int
10098 /
10099
10100Perform an fstatvfs system call on the given fd.
10101
10102Equivalent to statvfs(fd).
10103[clinic start generated code]*/
10104
Larry Hastings2f936352014-08-05 14:04:04 +100010105static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010106os_fstatvfs_impl(PyObject *module, int fd)
10107/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010108{
10109 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010110 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010112
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010113 do {
10114 Py_BEGIN_ALLOW_THREADS
10115 result = fstatvfs(fd, &st);
10116 Py_END_ALLOW_THREADS
10117 } while (result != 0 && errno == EINTR &&
10118 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010119 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010120 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010121
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010123}
Larry Hastings2f936352014-08-05 14:04:04 +100010124#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010125
10126
Thomas Wouters477c8d52006-05-27 19:21:47 +000010127#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010128#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010129/*[clinic input]
10130os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010131
Larry Hastings2f936352014-08-05 14:04:04 +100010132 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10133
10134Perform a statvfs system call on the given path.
10135
10136path may always be specified as a string.
10137On some platforms, path may also be specified as an open file descriptor.
10138 If this functionality is unavailable, using it raises an exception.
10139[clinic start generated code]*/
10140
Larry Hastings2f936352014-08-05 14:04:04 +100010141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010142os_statvfs_impl(PyObject *module, path_t *path)
10143/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010144{
10145 int result;
10146 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010147
10148 Py_BEGIN_ALLOW_THREADS
10149#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010150 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010151#ifdef __APPLE__
10152 /* handle weak-linking on Mac OS X 10.3 */
10153 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010154 fd_specified("statvfs", path->fd);
10155 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010156 }
10157#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010158 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010159 }
10160 else
10161#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010162 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010163 Py_END_ALLOW_THREADS
10164
10165 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010166 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010167 }
10168
Larry Hastings2f936352014-08-05 14:04:04 +100010169 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010170}
Larry Hastings2f936352014-08-05 14:04:04 +100010171#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10172
Guido van Rossum94f6f721999-01-06 18:42:14 +000010173
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010174#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010175/*[clinic input]
10176os._getdiskusage
10177
Steve Dower23ad6d02018-02-22 10:39:10 -080010178 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010179
10180Return disk usage statistics about the given path as a (total, free) tuple.
10181[clinic start generated code]*/
10182
Larry Hastings2f936352014-08-05 14:04:04 +100010183static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010184os__getdiskusage_impl(PyObject *module, path_t *path)
10185/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010186{
10187 BOOL retval;
10188 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010189 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010190
10191 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010192 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010193 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010194 if (retval == 0) {
10195 if (GetLastError() == ERROR_DIRECTORY) {
10196 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010197
Joe Pamerc8c02492018-09-25 10:57:36 -040010198 dir_path = PyMem_New(wchar_t, path->length + 1);
10199 if (dir_path == NULL) {
10200 return PyErr_NoMemory();
10201 }
10202
10203 wcscpy_s(dir_path, path->length + 1, path->wide);
10204
10205 if (_dirnameW(dir_path) != -1) {
10206 Py_BEGIN_ALLOW_THREADS
10207 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10208 Py_END_ALLOW_THREADS
10209 }
10210 /* Record the last error in case it's modified by PyMem_Free. */
10211 err = GetLastError();
10212 PyMem_Free(dir_path);
10213 if (retval) {
10214 goto success;
10215 }
10216 }
10217 return PyErr_SetFromWindowsErr(err);
10218 }
10219
10220success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010221 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10222}
Larry Hastings2f936352014-08-05 14:04:04 +100010223#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010224
10225
Fred Drakec9680921999-12-13 16:37:25 +000010226/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10227 * It maps strings representing configuration variable names to
10228 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010229 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010230 * rarely-used constants. There are three separate tables that use
10231 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010232 *
10233 * This code is always included, even if none of the interfaces that
10234 * need it are included. The #if hackery needed to avoid it would be
10235 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010236 */
10237struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010238 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010239 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010240};
10241
Fred Drake12c6e2d1999-12-14 21:25:03 +000010242static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010243conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010244 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010245{
Christian Heimes217cfd12007-12-02 14:31:20 +000010246 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010247 int value = _PyLong_AsInt(arg);
10248 if (value == -1 && PyErr_Occurred())
10249 return 0;
10250 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010251 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010252 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010253 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010254 /* look up the value in the table using a binary search */
10255 size_t lo = 0;
10256 size_t mid;
10257 size_t hi = tablesize;
10258 int cmp;
10259 const char *confname;
10260 if (!PyUnicode_Check(arg)) {
10261 PyErr_SetString(PyExc_TypeError,
10262 "configuration names must be strings or integers");
10263 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010265 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010266 if (confname == NULL)
10267 return 0;
10268 while (lo < hi) {
10269 mid = (lo + hi) / 2;
10270 cmp = strcmp(confname, table[mid].name);
10271 if (cmp < 0)
10272 hi = mid;
10273 else if (cmp > 0)
10274 lo = mid + 1;
10275 else {
10276 *valuep = table[mid].value;
10277 return 1;
10278 }
10279 }
10280 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10281 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010283}
10284
10285
10286#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10287static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010288#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010290#endif
10291#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010293#endif
Fred Drakec9680921999-12-13 16:37:25 +000010294#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010339#ifdef _PC_ACL_ENABLED
10340 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10341#endif
10342#ifdef _PC_MIN_HOLE_SIZE
10343 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10344#endif
10345#ifdef _PC_ALLOC_SIZE_MIN
10346 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10347#endif
10348#ifdef _PC_REC_INCR_XFER_SIZE
10349 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10350#endif
10351#ifdef _PC_REC_MAX_XFER_SIZE
10352 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10353#endif
10354#ifdef _PC_REC_MIN_XFER_SIZE
10355 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10356#endif
10357#ifdef _PC_REC_XFER_ALIGN
10358 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10359#endif
10360#ifdef _PC_SYMLINK_MAX
10361 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10362#endif
10363#ifdef _PC_XATTR_ENABLED
10364 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10365#endif
10366#ifdef _PC_XATTR_EXISTS
10367 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10368#endif
10369#ifdef _PC_TIMESTAMP_RESOLUTION
10370 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10371#endif
Fred Drakec9680921999-12-13 16:37:25 +000010372};
10373
Fred Drakec9680921999-12-13 16:37:25 +000010374static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010375conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010376{
10377 return conv_confname(arg, valuep, posix_constants_pathconf,
10378 sizeof(posix_constants_pathconf)
10379 / sizeof(struct constdef));
10380}
10381#endif
10382
Larry Hastings2f936352014-08-05 14:04:04 +100010383
Fred Drakec9680921999-12-13 16:37:25 +000010384#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010385/*[clinic input]
10386os.fpathconf -> long
10387
10388 fd: int
10389 name: path_confname
10390 /
10391
10392Return the configuration limit name for the file descriptor fd.
10393
10394If there is no limit, return -1.
10395[clinic start generated code]*/
10396
Larry Hastings2f936352014-08-05 14:04:04 +100010397static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010398os_fpathconf_impl(PyObject *module, int fd, int name)
10399/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010400{
10401 long limit;
10402
10403 errno = 0;
10404 limit = fpathconf(fd, name);
10405 if (limit == -1 && errno != 0)
10406 posix_error();
10407
10408 return limit;
10409}
10410#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010411
10412
10413#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010414/*[clinic input]
10415os.pathconf -> long
10416 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10417 name: path_confname
10418
10419Return the configuration limit name for the file or directory path.
10420
10421If there is no limit, return -1.
10422On some platforms, path may also be specified as an open file descriptor.
10423 If this functionality is unavailable, using it raises an exception.
10424[clinic start generated code]*/
10425
Larry Hastings2f936352014-08-05 14:04:04 +100010426static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010427os_pathconf_impl(PyObject *module, path_t *path, int name)
10428/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010429{
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010431
Victor Stinner8c62be82010-05-06 00:08:46 +000010432 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010433#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010434 if (path->fd != -1)
10435 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010436 else
10437#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010438 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 if (limit == -1 && errno != 0) {
10440 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010441 /* could be a path or name problem */
10442 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010443 else
Larry Hastings2f936352014-08-05 14:04:04 +100010444 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 }
Larry Hastings2f936352014-08-05 14:04:04 +100010446
10447 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010448}
Larry Hastings2f936352014-08-05 14:04:04 +100010449#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010450
10451#ifdef HAVE_CONFSTR
10452static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010453#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010455#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010456#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010458#endif
10459#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010461#endif
Fred Draked86ed291999-12-15 15:34:33 +000010462#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010464#endif
10465#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010467#endif
10468#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010470#endif
10471#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010473#endif
Fred Drakec9680921999-12-13 16:37:25 +000010474#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010476#endif
10477#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010479#endif
10480#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010482#endif
10483#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010485#endif
10486#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
Fred Draked86ed291999-12-15 15:34:33 +000010498#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010500#endif
Fred Drakec9680921999-12-13 16:37:25 +000010501#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010503#endif
Fred Draked86ed291999-12-15 15:34:33 +000010504#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010506#endif
10507#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010509#endif
10510#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010512#endif
10513#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010515#endif
Fred Drakec9680921999-12-13 16:37:25 +000010516#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
Fred Draked86ed291999-12-15 15:34:33 +000010564#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010566#endif
10567#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010569#endif
10570#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010572#endif
10573#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010575#endif
10576#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010578#endif
10579#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010581#endif
10582#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010584#endif
10585#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010587#endif
10588#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010590#endif
10591#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010593#endif
10594#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010596#endif
10597#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010599#endif
10600#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010602#endif
Fred Drakec9680921999-12-13 16:37:25 +000010603};
10604
10605static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010606conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010607{
10608 return conv_confname(arg, valuep, posix_constants_confstr,
10609 sizeof(posix_constants_confstr)
10610 / sizeof(struct constdef));
10611}
10612
Larry Hastings2f936352014-08-05 14:04:04 +100010613
10614/*[clinic input]
10615os.confstr
10616
10617 name: confstr_confname
10618 /
10619
10620Return a string-valued system configuration variable.
10621[clinic start generated code]*/
10622
Larry Hastings2f936352014-08-05 14:04:04 +100010623static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010624os_confstr_impl(PyObject *module, int name)
10625/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010626{
10627 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010628 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010629 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010630
Victor Stinnercb043522010-09-10 23:49:04 +000010631 errno = 0;
10632 len = confstr(name, buffer, sizeof(buffer));
10633 if (len == 0) {
10634 if (errno) {
10635 posix_error();
10636 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010637 }
10638 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010639 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010640 }
10641 }
Victor Stinnercb043522010-09-10 23:49:04 +000010642
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010643 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010644 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010645 char *buf = PyMem_Malloc(len);
10646 if (buf == NULL)
10647 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010648 len2 = confstr(name, buf, len);
10649 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010650 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010651 PyMem_Free(buf);
10652 }
10653 else
10654 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010655 return result;
10656}
Larry Hastings2f936352014-08-05 14:04:04 +100010657#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010658
10659
10660#ifdef HAVE_SYSCONF
10661static struct constdef posix_constants_sysconf[] = {
10662#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010664#endif
10665#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010667#endif
10668#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010670#endif
10671#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010673#endif
10674#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010676#endif
10677#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
10680#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
10683#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010685#endif
10686#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
10689#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010691#endif
Fred Draked86ed291999-12-15 15:34:33 +000010692#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010694#endif
10695#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010697#endif
Fred Drakec9680921999-12-13 16:37:25 +000010698#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010700#endif
Fred Drakec9680921999-12-13 16:37:25 +000010701#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010703#endif
10704#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010706#endif
10707#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010709#endif
10710#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010712#endif
10713#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010715#endif
Fred Draked86ed291999-12-15 15:34:33 +000010716#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010718#endif
Fred Drakec9680921999-12-13 16:37:25 +000010719#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010721#endif
10722#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010724#endif
10725#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010727#endif
10728#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010730#endif
10731#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010733#endif
Fred Draked86ed291999-12-15 15:34:33 +000010734#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010736#endif
Fred Drakec9680921999-12-13 16:37:25 +000010737#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010739#endif
10740#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010742#endif
10743#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010745#endif
10746#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010748#endif
10749#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010751#endif
10752#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010754#endif
10755#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010757#endif
10758#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010760#endif
10761#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010763#endif
10764#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010766#endif
10767#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010769#endif
10770#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010772#endif
10773#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010775#endif
10776#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010778#endif
10779#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010781#endif
10782#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010784#endif
10785#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010787#endif
10788#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010790#endif
10791#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010793#endif
10794#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010795 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010796#endif
10797#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010798 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010799#endif
10800#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010802#endif
10803#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010805#endif
Fred Draked86ed291999-12-15 15:34:33 +000010806#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010808#endif
Fred Drakec9680921999-12-13 16:37:25 +000010809#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010811#endif
10812#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010814#endif
10815#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010817#endif
Fred Draked86ed291999-12-15 15:34:33 +000010818#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010820#endif
Fred Drakec9680921999-12-13 16:37:25 +000010821#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010823#endif
Fred Draked86ed291999-12-15 15:34:33 +000010824#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010826#endif
10827#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010829#endif
Fred Drakec9680921999-12-13 16:37:25 +000010830#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010832#endif
10833#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010835#endif
10836#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010838#endif
10839#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010841#endif
Fred Draked86ed291999-12-15 15:34:33 +000010842#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010844#endif
Fred Drakec9680921999-12-13 16:37:25 +000010845#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010847#endif
10848#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010850#endif
10851#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010853#endif
10854#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010856#endif
10857#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010859#endif
10860#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010862#endif
10863#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010865#endif
Fred Draked86ed291999-12-15 15:34:33 +000010866#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010868#endif
Fred Drakec9680921999-12-13 16:37:25 +000010869#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010871#endif
10872#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010874#endif
Fred Draked86ed291999-12-15 15:34:33 +000010875#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010877#endif
Fred Drakec9680921999-12-13 16:37:25 +000010878#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010880#endif
10881#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010883#endif
10884#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010886#endif
10887#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
10890#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
10893#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
Fred Draked86ed291999-12-15 15:34:33 +000010905#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010907#endif
10908#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010910#endif
Fred Drakec9680921999-12-13 16:37:25 +000010911#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010913#endif
10914#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010916#endif
10917#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010919#endif
10920#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010922#endif
10923#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010925#endif
10926#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010928#endif
10929#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010931#endif
10932#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010934#endif
10935#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
10938#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010940#endif
10941#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010943#endif
10944#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010946#endif
10947#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010949#endif
10950#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010952#endif
10953#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010955#endif
10956#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010958#endif
10959#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010961#endif
10962#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010964#endif
10965#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
10968#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010970#endif
10971#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010973#endif
10974#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010976#endif
10977#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010979#endif
10980#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010982#endif
10983#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010985#endif
10986#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010988#endif
10989#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010991#endif
10992#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010994#endif
10995#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010997#endif
10998#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011000#endif
11001#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011003#endif
11004#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011006#endif
11007#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011009#endif
11010#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011012#endif
11013#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011015#endif
Fred Draked86ed291999-12-15 15:34:33 +000011016#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011018#endif
Fred Drakec9680921999-12-13 16:37:25 +000011019#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011021#endif
11022#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011024#endif
11025#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011027#endif
11028#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011030#endif
11031#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011033#endif
11034#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011036#endif
11037#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011039#endif
11040#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011042#endif
11043#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011045#endif
11046#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011048#endif
11049#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011051#endif
11052#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011054#endif
11055#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011057#endif
11058#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011060#endif
11061#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011063#endif
11064#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011066#endif
11067#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011069#endif
11070#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011072#endif
11073#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011075#endif
11076#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011078#endif
11079#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011081#endif
11082#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011084#endif
11085#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011087#endif
11088#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011090#endif
11091#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011093#endif
11094#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011096#endif
11097#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011099#endif
11100#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011102#endif
11103#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
11106#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
11121#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
11124#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011126#endif
11127#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011129#endif
11130#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011132#endif
11133#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011135#endif
11136#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011138#endif
11139#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011141#endif
11142#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011144#endif
11145#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011147#endif
11148#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011150#endif
11151#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011153#endif
11154};
11155
11156static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011157conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011158{
11159 return conv_confname(arg, valuep, posix_constants_sysconf,
11160 sizeof(posix_constants_sysconf)
11161 / sizeof(struct constdef));
11162}
11163
Larry Hastings2f936352014-08-05 14:04:04 +100011164
11165/*[clinic input]
11166os.sysconf -> long
11167 name: sysconf_confname
11168 /
11169
11170Return an integer-valued system configuration variable.
11171[clinic start generated code]*/
11172
Larry Hastings2f936352014-08-05 14:04:04 +100011173static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011174os_sysconf_impl(PyObject *module, int name)
11175/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011176{
11177 long value;
11178
11179 errno = 0;
11180 value = sysconf(name);
11181 if (value == -1 && errno != 0)
11182 posix_error();
11183 return value;
11184}
11185#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011186
11187
Fred Drakebec628d1999-12-15 18:31:10 +000011188/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011189 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011190 * the exported dictionaries that are used to publish information about the
11191 * names available on the host platform.
11192 *
11193 * Sorting the table at runtime ensures that the table is properly ordered
11194 * when used, even for platforms we're not able to test on. It also makes
11195 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011196 */
Fred Drakebec628d1999-12-15 18:31:10 +000011197
11198static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011199cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011200{
11201 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011203 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011204 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011205
11206 return strcmp(c1->name, c2->name);
11207}
11208
11209static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011210setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011211 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011212{
Fred Drakebec628d1999-12-15 18:31:10 +000011213 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011214 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011215
11216 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11217 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011218 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011220
Barry Warsaw3155db32000-04-13 15:20:40 +000011221 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 PyObject *o = PyLong_FromLong(table[i].value);
11223 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11224 Py_XDECREF(o);
11225 Py_DECREF(d);
11226 return -1;
11227 }
11228 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011229 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011230 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011231}
11232
Fred Drakebec628d1999-12-15 18:31:10 +000011233/* Return -1 on failure, 0 on success. */
11234static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011235setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011236{
11237#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011238 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011239 sizeof(posix_constants_pathconf)
11240 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011241 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011242 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011243#endif
11244#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011245 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011246 sizeof(posix_constants_confstr)
11247 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011248 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011249 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011250#endif
11251#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011252 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011253 sizeof(posix_constants_sysconf)
11254 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011255 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011256 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011257#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011258 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011259}
Fred Draked86ed291999-12-15 15:34:33 +000011260
11261
Larry Hastings2f936352014-08-05 14:04:04 +100011262/*[clinic input]
11263os.abort
11264
11265Abort the interpreter immediately.
11266
11267This function 'dumps core' or otherwise fails in the hardest way possible
11268on the hosting operating system. This function never returns.
11269[clinic start generated code]*/
11270
Larry Hastings2f936352014-08-05 14:04:04 +100011271static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011272os_abort_impl(PyObject *module)
11273/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011274{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011275 abort();
11276 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011277#ifndef __clang__
11278 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11279 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11280 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011281 Py_FatalError("abort() called from Python code didn't abort!");
11282 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011283#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011284}
Fred Drakebec628d1999-12-15 18:31:10 +000011285
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011286#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011287/* Grab ShellExecute dynamically from shell32 */
11288static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011289static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11290 LPCWSTR, INT);
11291static int
11292check_ShellExecute()
11293{
11294 HINSTANCE hShell32;
11295
11296 /* only recheck */
11297 if (-1 == has_ShellExecute) {
11298 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011299 /* Security note: this call is not vulnerable to "DLL hijacking".
11300 SHELL32 is part of "KnownDLLs" and so Windows always load
11301 the system SHELL32.DLL, even if there is another SHELL32.DLL
11302 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011303 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011304 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011305 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11306 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011307 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011308 } else {
11309 has_ShellExecute = 0;
11310 }
Tony Roberts4860f012019-02-02 18:16:42 +010011311 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011312 }
11313 return has_ShellExecute;
11314}
11315
11316
Steve Dowercc16be82016-09-08 10:35:16 -070011317/*[clinic input]
11318os.startfile
11319 filepath: path_t
11320 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011321
Steve Dowercc16be82016-09-08 10:35:16 -070011322startfile(filepath [, operation])
11323
11324Start a file with its associated application.
11325
11326When "operation" is not specified or "open", this acts like
11327double-clicking the file in Explorer, or giving the file name as an
11328argument to the DOS "start" command: the file is opened with whatever
11329application (if any) its extension is associated.
11330When another "operation" is given, it specifies what should be done with
11331the file. A typical operation is "print".
11332
11333startfile returns as soon as the associated application is launched.
11334There is no option to wait for the application to close, and no way
11335to retrieve the application's exit status.
11336
11337The filepath is relative to the current directory. If you want to use
11338an absolute path, make sure the first character is not a slash ("/");
11339the underlying Win32 ShellExecute function doesn't work if it is.
11340[clinic start generated code]*/
11341
11342static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011343os_startfile_impl(PyObject *module, path_t *filepath,
11344 const Py_UNICODE *operation)
11345/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011346{
11347 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011348
11349 if(!check_ShellExecute()) {
11350 /* If the OS doesn't have ShellExecute, return a
11351 NotImplementedError. */
11352 return PyErr_Format(PyExc_NotImplementedError,
11353 "startfile not available on this platform");
11354 }
11355
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011357 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011358 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 Py_END_ALLOW_THREADS
11360
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011362 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011363 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 }
Steve Dowercc16be82016-09-08 10:35:16 -070011365 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011366}
Larry Hastings2f936352014-08-05 14:04:04 +100011367#endif /* MS_WINDOWS */
11368
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011369
Martin v. Löwis438b5342002-12-27 10:16:42 +000011370#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011371/*[clinic input]
11372os.getloadavg
11373
11374Return average recent system load information.
11375
11376Return the number of processes in the system run queue averaged over
11377the last 1, 5, and 15 minutes as a tuple of three floats.
11378Raises OSError if the load average was unobtainable.
11379[clinic start generated code]*/
11380
Larry Hastings2f936352014-08-05 14:04:04 +100011381static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011382os_getloadavg_impl(PyObject *module)
11383/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011384{
11385 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011386 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011387 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11388 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011389 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011390 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011391}
Larry Hastings2f936352014-08-05 14:04:04 +100011392#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011393
Larry Hastings2f936352014-08-05 14:04:04 +100011394
11395/*[clinic input]
11396os.device_encoding
11397 fd: int
11398
11399Return a string describing the encoding of a terminal's file descriptor.
11400
11401The file descriptor must be attached to a terminal.
11402If the device is not a terminal, return None.
11403[clinic start generated code]*/
11404
Larry Hastings2f936352014-08-05 14:04:04 +100011405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011406os_device_encoding_impl(PyObject *module, int fd)
11407/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011408{
Brett Cannonefb00c02012-02-29 18:31:31 -050011409 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011410}
11411
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011412
Larry Hastings2f936352014-08-05 14:04:04 +100011413#ifdef HAVE_SETRESUID
11414/*[clinic input]
11415os.setresuid
11416
11417 ruid: uid_t
11418 euid: uid_t
11419 suid: uid_t
11420 /
11421
11422Set the current process's real, effective, and saved user ids.
11423[clinic start generated code]*/
11424
Larry Hastings2f936352014-08-05 14:04:04 +100011425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011426os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11427/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011428{
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 if (setresuid(ruid, euid, suid) < 0)
11430 return posix_error();
11431 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011432}
Larry Hastings2f936352014-08-05 14:04:04 +100011433#endif /* HAVE_SETRESUID */
11434
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011435
11436#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011437/*[clinic input]
11438os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011439
Larry Hastings2f936352014-08-05 14:04:04 +100011440 rgid: gid_t
11441 egid: gid_t
11442 sgid: gid_t
11443 /
11444
11445Set the current process's real, effective, and saved group ids.
11446[clinic start generated code]*/
11447
Larry Hastings2f936352014-08-05 14:04:04 +100011448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011449os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11450/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011451{
Victor Stinner8c62be82010-05-06 00:08:46 +000011452 if (setresgid(rgid, egid, sgid) < 0)
11453 return posix_error();
11454 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011455}
Larry Hastings2f936352014-08-05 14:04:04 +100011456#endif /* HAVE_SETRESGID */
11457
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011458
11459#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011460/*[clinic input]
11461os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011462
Larry Hastings2f936352014-08-05 14:04:04 +100011463Return a tuple of the current process's real, effective, and saved user ids.
11464[clinic start generated code]*/
11465
Larry Hastings2f936352014-08-05 14:04:04 +100011466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011467os_getresuid_impl(PyObject *module)
11468/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011469{
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 if (getresuid(&ruid, &euid, &suid) < 0)
11472 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011473 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11474 _PyLong_FromUid(euid),
11475 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011476}
Larry Hastings2f936352014-08-05 14:04:04 +100011477#endif /* HAVE_GETRESUID */
11478
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011479
11480#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011481/*[clinic input]
11482os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011483
Larry Hastings2f936352014-08-05 14:04:04 +100011484Return a tuple of the current process's real, effective, and saved group ids.
11485[clinic start generated code]*/
11486
Larry Hastings2f936352014-08-05 14:04:04 +100011487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011488os_getresgid_impl(PyObject *module)
11489/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011490{
11491 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 if (getresgid(&rgid, &egid, &sgid) < 0)
11493 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011494 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11495 _PyLong_FromGid(egid),
11496 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011497}
Larry Hastings2f936352014-08-05 14:04:04 +100011498#endif /* HAVE_GETRESGID */
11499
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011500
Benjamin Peterson9428d532011-09-14 11:45:52 -040011501#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011502/*[clinic input]
11503os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011504
Larry Hastings2f936352014-08-05 14:04:04 +100011505 path: path_t(allow_fd=True)
11506 attribute: path_t
11507 *
11508 follow_symlinks: bool = True
11509
11510Return the value of extended attribute attribute on path.
11511
BNMetricsb9427072018-11-02 15:20:19 +000011512path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011513If follow_symlinks is False, and the last element of the path is a symbolic
11514 link, getxattr will examine the symbolic link itself instead of the file
11515 the link points to.
11516
11517[clinic start generated code]*/
11518
Larry Hastings2f936352014-08-05 14:04:04 +100011519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011520os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011521 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011522/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011523{
11524 Py_ssize_t i;
11525 PyObject *buffer = NULL;
11526
11527 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11528 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011529
Larry Hastings9cf065c2012-06-22 16:30:09 -070011530 for (i = 0; ; i++) {
11531 void *ptr;
11532 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011533 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011534 Py_ssize_t buffer_size = buffer_sizes[i];
11535 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011536 path_error(path);
11537 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011538 }
11539 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11540 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011541 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011542 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011543
Larry Hastings9cf065c2012-06-22 16:30:09 -070011544 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011545 if (path->fd >= 0)
11546 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011547 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011548 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011549 else
Larry Hastings2f936352014-08-05 14:04:04 +100011550 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011551 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011552
Larry Hastings9cf065c2012-06-22 16:30:09 -070011553 if (result < 0) {
11554 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011555 if (errno == ERANGE)
11556 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011557 path_error(path);
11558 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011559 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011560
Larry Hastings9cf065c2012-06-22 16:30:09 -070011561 if (result != buffer_size) {
11562 /* Can only shrink. */
11563 _PyBytes_Resize(&buffer, result);
11564 }
11565 break;
11566 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011567
Larry Hastings9cf065c2012-06-22 16:30:09 -070011568 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011569}
11570
Larry Hastings2f936352014-08-05 14:04:04 +100011571
11572/*[clinic input]
11573os.setxattr
11574
11575 path: path_t(allow_fd=True)
11576 attribute: path_t
11577 value: Py_buffer
11578 flags: int = 0
11579 *
11580 follow_symlinks: bool = True
11581
11582Set extended attribute attribute on path to value.
11583
BNMetricsb9427072018-11-02 15:20:19 +000011584path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011585If follow_symlinks is False, and the last element of the path is a symbolic
11586 link, setxattr will modify the symbolic link itself instead of the file
11587 the link points to.
11588
11589[clinic start generated code]*/
11590
Benjamin Peterson799bd802011-08-31 22:15:17 -040011591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011592os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011593 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011594/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011595{
Larry Hastings2f936352014-08-05 14:04:04 +100011596 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011597
Larry Hastings2f936352014-08-05 14:04:04 +100011598 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011599 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011600
Benjamin Peterson799bd802011-08-31 22:15:17 -040011601 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011602 if (path->fd > -1)
11603 result = fsetxattr(path->fd, attribute->narrow,
11604 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011605 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011606 result = setxattr(path->narrow, attribute->narrow,
11607 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011608 else
Larry Hastings2f936352014-08-05 14:04:04 +100011609 result = lsetxattr(path->narrow, attribute->narrow,
11610 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011611 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011612
Larry Hastings9cf065c2012-06-22 16:30:09 -070011613 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011614 path_error(path);
11615 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011616 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011617
Larry Hastings2f936352014-08-05 14:04:04 +100011618 Py_RETURN_NONE;
11619}
11620
11621
11622/*[clinic input]
11623os.removexattr
11624
11625 path: path_t(allow_fd=True)
11626 attribute: path_t
11627 *
11628 follow_symlinks: bool = True
11629
11630Remove extended attribute attribute on path.
11631
BNMetricsb9427072018-11-02 15:20:19 +000011632path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011633If follow_symlinks is False, and the last element of the path is a symbolic
11634 link, removexattr will modify the symbolic link itself instead of the file
11635 the link points to.
11636
11637[clinic start generated code]*/
11638
Larry Hastings2f936352014-08-05 14:04:04 +100011639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011640os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011641 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011642/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011643{
11644 ssize_t result;
11645
11646 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11647 return NULL;
11648
11649 Py_BEGIN_ALLOW_THREADS;
11650 if (path->fd > -1)
11651 result = fremovexattr(path->fd, attribute->narrow);
11652 else if (follow_symlinks)
11653 result = removexattr(path->narrow, attribute->narrow);
11654 else
11655 result = lremovexattr(path->narrow, attribute->narrow);
11656 Py_END_ALLOW_THREADS;
11657
11658 if (result) {
11659 return path_error(path);
11660 }
11661
11662 Py_RETURN_NONE;
11663}
11664
11665
11666/*[clinic input]
11667os.listxattr
11668
11669 path: path_t(allow_fd=True, nullable=True) = None
11670 *
11671 follow_symlinks: bool = True
11672
11673Return a list of extended attributes on path.
11674
BNMetricsb9427072018-11-02 15:20:19 +000011675path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011676if path is None, listxattr will examine the current directory.
11677If follow_symlinks is False, and the last element of the path is a symbolic
11678 link, listxattr will examine the symbolic link itself instead of the file
11679 the link points to.
11680[clinic start generated code]*/
11681
Larry Hastings2f936352014-08-05 14:04:04 +100011682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011683os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011684/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011685{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011686 Py_ssize_t i;
11687 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011688 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011689 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011690
Larry Hastings2f936352014-08-05 14:04:04 +100011691 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011692 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011693
Larry Hastings2f936352014-08-05 14:04:04 +100011694 name = path->narrow ? path->narrow : ".";
11695
Larry Hastings9cf065c2012-06-22 16:30:09 -070011696 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011697 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011698 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011699 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011700 Py_ssize_t buffer_size = buffer_sizes[i];
11701 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011702 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011703 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011704 break;
11705 }
11706 buffer = PyMem_MALLOC(buffer_size);
11707 if (!buffer) {
11708 PyErr_NoMemory();
11709 break;
11710 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011711
Larry Hastings9cf065c2012-06-22 16:30:09 -070011712 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011713 if (path->fd > -1)
11714 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011715 else if (follow_symlinks)
11716 length = listxattr(name, buffer, buffer_size);
11717 else
11718 length = llistxattr(name, buffer, buffer_size);
11719 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011720
Larry Hastings9cf065c2012-06-22 16:30:09 -070011721 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011722 if (errno == ERANGE) {
11723 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011724 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011725 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011726 }
Larry Hastings2f936352014-08-05 14:04:04 +100011727 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011728 break;
11729 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011730
Larry Hastings9cf065c2012-06-22 16:30:09 -070011731 result = PyList_New(0);
11732 if (!result) {
11733 goto exit;
11734 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011735
Larry Hastings9cf065c2012-06-22 16:30:09 -070011736 end = buffer + length;
11737 for (trace = start = buffer; trace != end; trace++) {
11738 if (!*trace) {
11739 int error;
11740 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11741 trace - start);
11742 if (!attribute) {
11743 Py_DECREF(result);
11744 result = NULL;
11745 goto exit;
11746 }
11747 error = PyList_Append(result, attribute);
11748 Py_DECREF(attribute);
11749 if (error) {
11750 Py_DECREF(result);
11751 result = NULL;
11752 goto exit;
11753 }
11754 start = trace + 1;
11755 }
11756 }
11757 break;
11758 }
11759exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011760 if (buffer)
11761 PyMem_FREE(buffer);
11762 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011763}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011764#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011765
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011766
Larry Hastings2f936352014-08-05 14:04:04 +100011767/*[clinic input]
11768os.urandom
11769
11770 size: Py_ssize_t
11771 /
11772
11773Return a bytes object containing random bytes suitable for cryptographic use.
11774[clinic start generated code]*/
11775
Larry Hastings2f936352014-08-05 14:04:04 +100011776static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011777os_urandom_impl(PyObject *module, Py_ssize_t size)
11778/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011779{
11780 PyObject *bytes;
11781 int result;
11782
Georg Brandl2fb477c2012-02-21 00:33:36 +010011783 if (size < 0)
11784 return PyErr_Format(PyExc_ValueError,
11785 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011786 bytes = PyBytes_FromStringAndSize(NULL, size);
11787 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011788 return NULL;
11789
Victor Stinnere66987e2016-09-06 16:33:52 -070011790 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011791 if (result == -1) {
11792 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011793 return NULL;
11794 }
Larry Hastings2f936352014-08-05 14:04:04 +100011795 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011796}
11797
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011798/* Terminal size querying */
11799
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011800static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011801
11802PyDoc_STRVAR(TerminalSize_docstring,
11803 "A tuple of (columns, lines) for holding terminal window size");
11804
11805static PyStructSequence_Field TerminalSize_fields[] = {
11806 {"columns", "width of the terminal window in characters"},
11807 {"lines", "height of the terminal window in characters"},
11808 {NULL, NULL}
11809};
11810
11811static PyStructSequence_Desc TerminalSize_desc = {
11812 "os.terminal_size",
11813 TerminalSize_docstring,
11814 TerminalSize_fields,
11815 2,
11816};
11817
11818#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011819/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011820PyDoc_STRVAR(termsize__doc__,
11821 "Return the size of the terminal window as (columns, lines).\n" \
11822 "\n" \
11823 "The optional argument fd (default standard output) specifies\n" \
11824 "which file descriptor should be queried.\n" \
11825 "\n" \
11826 "If the file descriptor is not connected to a terminal, an OSError\n" \
11827 "is thrown.\n" \
11828 "\n" \
11829 "This function will only be defined if an implementation is\n" \
11830 "available for this system.\n" \
11831 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011832 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011833 "normally be used, os.get_terminal_size is the low-level implementation.");
11834
11835static PyObject*
11836get_terminal_size(PyObject *self, PyObject *args)
11837{
11838 int columns, lines;
11839 PyObject *termsize;
11840
11841 int fd = fileno(stdout);
11842 /* Under some conditions stdout may not be connected and
11843 * fileno(stdout) may point to an invalid file descriptor. For example
11844 * GUI apps don't have valid standard streams by default.
11845 *
11846 * If this happens, and the optional fd argument is not present,
11847 * the ioctl below will fail returning EBADF. This is what we want.
11848 */
11849
11850 if (!PyArg_ParseTuple(args, "|i", &fd))
11851 return NULL;
11852
11853#ifdef TERMSIZE_USE_IOCTL
11854 {
11855 struct winsize w;
11856 if (ioctl(fd, TIOCGWINSZ, &w))
11857 return PyErr_SetFromErrno(PyExc_OSError);
11858 columns = w.ws_col;
11859 lines = w.ws_row;
11860 }
11861#endif /* TERMSIZE_USE_IOCTL */
11862
11863#ifdef TERMSIZE_USE_CONIO
11864 {
11865 DWORD nhandle;
11866 HANDLE handle;
11867 CONSOLE_SCREEN_BUFFER_INFO csbi;
11868 switch (fd) {
11869 case 0: nhandle = STD_INPUT_HANDLE;
11870 break;
11871 case 1: nhandle = STD_OUTPUT_HANDLE;
11872 break;
11873 case 2: nhandle = STD_ERROR_HANDLE;
11874 break;
11875 default:
11876 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11877 }
11878 handle = GetStdHandle(nhandle);
11879 if (handle == NULL)
11880 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11881 if (handle == INVALID_HANDLE_VALUE)
11882 return PyErr_SetFromWindowsErr(0);
11883
11884 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11885 return PyErr_SetFromWindowsErr(0);
11886
11887 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11888 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11889 }
11890#endif /* TERMSIZE_USE_CONIO */
11891
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011892 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011893 if (termsize == NULL)
11894 return NULL;
11895 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11896 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11897 if (PyErr_Occurred()) {
11898 Py_DECREF(termsize);
11899 return NULL;
11900 }
11901 return termsize;
11902}
11903#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11904
Larry Hastings2f936352014-08-05 14:04:04 +100011905
11906/*[clinic input]
11907os.cpu_count
11908
Charles-François Natali80d62e62015-08-13 20:37:08 +010011909Return the number of CPUs in the system; return None if indeterminable.
11910
11911This number is not equivalent to the number of CPUs the current process can
11912use. The number of usable CPUs can be obtained with
11913``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011914[clinic start generated code]*/
11915
Larry Hastings2f936352014-08-05 14:04:04 +100011916static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011917os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011918/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011919{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011920 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011921#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011922 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11923 Need to fallback to Vista behavior if this call isn't present */
11924 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011925 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010011926 Py_BEGIN_ALLOW_THREADS
11927 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011928 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11929 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010011930 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011931 if (_GetMaximumProcessorCount != NULL) {
11932 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11933 }
11934 else {
11935 SYSTEM_INFO sysinfo;
11936 GetSystemInfo(&sysinfo);
11937 ncpu = sysinfo.dwNumberOfProcessors;
11938 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011939#elif defined(__hpux)
11940 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11941#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11942 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011943#elif defined(__DragonFly__) || \
11944 defined(__OpenBSD__) || \
11945 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011946 defined(__NetBSD__) || \
11947 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011948 int mib[2];
11949 size_t len = sizeof(ncpu);
11950 mib[0] = CTL_HW;
11951 mib[1] = HW_NCPU;
11952 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11953 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011954#endif
11955 if (ncpu >= 1)
11956 return PyLong_FromLong(ncpu);
11957 else
11958 Py_RETURN_NONE;
11959}
11960
Victor Stinnerdaf45552013-08-28 00:53:59 +020011961
Larry Hastings2f936352014-08-05 14:04:04 +100011962/*[clinic input]
11963os.get_inheritable -> bool
11964
11965 fd: int
11966 /
11967
11968Get the close-on-exe flag of the specified file descriptor.
11969[clinic start generated code]*/
11970
Larry Hastings2f936352014-08-05 14:04:04 +100011971static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011972os_get_inheritable_impl(PyObject *module, int fd)
11973/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011974{
Steve Dower8fc89802015-04-12 00:26:27 -040011975 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011976 _Py_BEGIN_SUPPRESS_IPH
11977 return_value = _Py_get_inheritable(fd);
11978 _Py_END_SUPPRESS_IPH
11979 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011980}
11981
11982
11983/*[clinic input]
11984os.set_inheritable
11985 fd: int
11986 inheritable: int
11987 /
11988
11989Set the inheritable flag of the specified file descriptor.
11990[clinic start generated code]*/
11991
Larry Hastings2f936352014-08-05 14:04:04 +100011992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011993os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11994/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011995{
Steve Dower8fc89802015-04-12 00:26:27 -040011996 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011997
Steve Dower8fc89802015-04-12 00:26:27 -040011998 _Py_BEGIN_SUPPRESS_IPH
11999 result = _Py_set_inheritable(fd, inheritable, NULL);
12000 _Py_END_SUPPRESS_IPH
12001 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012002 return NULL;
12003 Py_RETURN_NONE;
12004}
12005
12006
12007#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012008/*[clinic input]
12009os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012010 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012011 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012012
Larry Hastings2f936352014-08-05 14:04:04 +100012013Get the close-on-exe flag of the specified file descriptor.
12014[clinic start generated code]*/
12015
Larry Hastings2f936352014-08-05 14:04:04 +100012016static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012017os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012018/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012019{
12020 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012021
12022 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12023 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012024 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012025 }
12026
Larry Hastings2f936352014-08-05 14:04:04 +100012027 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012028}
12029
Victor Stinnerdaf45552013-08-28 00:53:59 +020012030
Larry Hastings2f936352014-08-05 14:04:04 +100012031/*[clinic input]
12032os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012033 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012034 inheritable: bool
12035 /
12036
12037Set the inheritable flag of the specified handle.
12038[clinic start generated code]*/
12039
Larry Hastings2f936352014-08-05 14:04:04 +100012040static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012041os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012042 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012043/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012044{
12045 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012046 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12047 PyErr_SetFromWindowsErr(0);
12048 return NULL;
12049 }
12050 Py_RETURN_NONE;
12051}
Larry Hastings2f936352014-08-05 14:04:04 +100012052#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012053
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012054#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012055/*[clinic input]
12056os.get_blocking -> bool
12057 fd: int
12058 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012059
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012060Get the blocking mode of the file descriptor.
12061
12062Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12063[clinic start generated code]*/
12064
12065static int
12066os_get_blocking_impl(PyObject *module, int fd)
12067/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012068{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012069 int blocking;
12070
Steve Dower8fc89802015-04-12 00:26:27 -040012071 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012072 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012073 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012074 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012075}
12076
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012077/*[clinic input]
12078os.set_blocking
12079 fd: int
12080 blocking: bool(accept={int})
12081 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012082
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012083Set the blocking mode of the specified file descriptor.
12084
12085Set the O_NONBLOCK flag if blocking is False,
12086clear the O_NONBLOCK flag otherwise.
12087[clinic start generated code]*/
12088
12089static PyObject *
12090os_set_blocking_impl(PyObject *module, int fd, int blocking)
12091/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012092{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012093 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012094
Steve Dower8fc89802015-04-12 00:26:27 -040012095 _Py_BEGIN_SUPPRESS_IPH
12096 result = _Py_set_blocking(fd, blocking);
12097 _Py_END_SUPPRESS_IPH
12098 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012099 return NULL;
12100 Py_RETURN_NONE;
12101}
12102#endif /* !MS_WINDOWS */
12103
12104
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012105/*[clinic input]
12106class os.DirEntry "DirEntry *" "&DirEntryType"
12107[clinic start generated code]*/
12108/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012109
12110typedef struct {
12111 PyObject_HEAD
12112 PyObject *name;
12113 PyObject *path;
12114 PyObject *stat;
12115 PyObject *lstat;
12116#ifdef MS_WINDOWS
12117 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012118 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012119 int got_file_index;
12120#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012121#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012122 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012123#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012124 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012125 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012126#endif
12127} DirEntry;
12128
12129static void
12130DirEntry_dealloc(DirEntry *entry)
12131{
12132 Py_XDECREF(entry->name);
12133 Py_XDECREF(entry->path);
12134 Py_XDECREF(entry->stat);
12135 Py_XDECREF(entry->lstat);
12136 Py_TYPE(entry)->tp_free((PyObject *)entry);
12137}
12138
12139/* Forward reference */
12140static int
12141DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12142
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012143/*[clinic input]
12144os.DirEntry.is_symlink -> bool
12145
12146Return True if the entry is a symbolic link; cached per entry.
12147[clinic start generated code]*/
12148
Victor Stinner6036e442015-03-08 01:58:04 +010012149static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012150os_DirEntry_is_symlink_impl(DirEntry *self)
12151/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012152{
12153#ifdef MS_WINDOWS
12154 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012155#elif defined(HAVE_DIRENT_D_TYPE)
12156 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012157 if (self->d_type != DT_UNKNOWN)
12158 return self->d_type == DT_LNK;
12159 else
12160 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012161#else
12162 /* POSIX without d_type */
12163 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012164#endif
12165}
12166
12167static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012168DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12169{
12170 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012171 STRUCT_STAT st;
12172 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012173
12174#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012175 if (!PyUnicode_FSDecoder(self->path, &ub))
12176 return NULL;
12177 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012178#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012179 if (!PyUnicode_FSConverter(self->path, &ub))
12180 return NULL;
12181 const char *path = PyBytes_AS_STRING(ub);
12182 if (self->dir_fd != DEFAULT_DIR_FD) {
12183#ifdef HAVE_FSTATAT
12184 result = fstatat(self->dir_fd, path, &st,
12185 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12186#else
12187 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12188 return NULL;
12189#endif /* HAVE_FSTATAT */
12190 }
12191 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012192#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012193 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012194 if (follow_symlinks)
12195 result = STAT(path, &st);
12196 else
12197 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012198 }
12199 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012200
12201 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012202 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012203
12204 return _pystat_fromstructstat(&st);
12205}
12206
12207static PyObject *
12208DirEntry_get_lstat(DirEntry *self)
12209{
12210 if (!self->lstat) {
12211#ifdef MS_WINDOWS
12212 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12213#else /* POSIX */
12214 self->lstat = DirEntry_fetch_stat(self, 0);
12215#endif
12216 }
12217 Py_XINCREF(self->lstat);
12218 return self->lstat;
12219}
12220
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012221/*[clinic input]
12222os.DirEntry.stat
12223 *
12224 follow_symlinks: bool = True
12225
12226Return stat_result object for the entry; cached per entry.
12227[clinic start generated code]*/
12228
Victor Stinner6036e442015-03-08 01:58:04 +010012229static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012230os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12231/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012232{
12233 if (!follow_symlinks)
12234 return DirEntry_get_lstat(self);
12235
12236 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012237 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012238 if (result == -1)
12239 return NULL;
12240 else if (result)
12241 self->stat = DirEntry_fetch_stat(self, 1);
12242 else
12243 self->stat = DirEntry_get_lstat(self);
12244 }
12245
12246 Py_XINCREF(self->stat);
12247 return self->stat;
12248}
12249
Victor Stinner6036e442015-03-08 01:58:04 +010012250/* Set exception and return -1 on error, 0 for False, 1 for True */
12251static int
12252DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12253{
12254 PyObject *stat = NULL;
12255 PyObject *st_mode = NULL;
12256 long mode;
12257 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012258#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012259 int is_symlink;
12260 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012261#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012262#ifdef MS_WINDOWS
12263 unsigned long dir_bits;
12264#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012265 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012266
12267#ifdef MS_WINDOWS
12268 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12269 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012270#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012271 is_symlink = self->d_type == DT_LNK;
12272 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12273#endif
12274
Victor Stinner35a97c02015-03-08 02:59:09 +010012275#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012276 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012277#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012278 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012279 if (!stat) {
12280 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12281 /* If file doesn't exist (anymore), then return False
12282 (i.e., say it's not a file/directory) */
12283 PyErr_Clear();
12284 return 0;
12285 }
12286 goto error;
12287 }
12288 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12289 if (!st_mode)
12290 goto error;
12291
12292 mode = PyLong_AsLong(st_mode);
12293 if (mode == -1 && PyErr_Occurred())
12294 goto error;
12295 Py_CLEAR(st_mode);
12296 Py_CLEAR(stat);
12297 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012298#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012299 }
12300 else if (is_symlink) {
12301 assert(mode_bits != S_IFLNK);
12302 result = 0;
12303 }
12304 else {
12305 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12306#ifdef MS_WINDOWS
12307 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12308 if (mode_bits == S_IFDIR)
12309 result = dir_bits != 0;
12310 else
12311 result = dir_bits == 0;
12312#else /* POSIX */
12313 if (mode_bits == S_IFDIR)
12314 result = self->d_type == DT_DIR;
12315 else
12316 result = self->d_type == DT_REG;
12317#endif
12318 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012319#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012320
12321 return result;
12322
12323error:
12324 Py_XDECREF(st_mode);
12325 Py_XDECREF(stat);
12326 return -1;
12327}
12328
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012329/*[clinic input]
12330os.DirEntry.is_dir -> bool
12331 *
12332 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012333
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012334Return True if the entry is a directory; cached per entry.
12335[clinic start generated code]*/
12336
12337static int
12338os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12339/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12340{
12341 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012342}
12343
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012344/*[clinic input]
12345os.DirEntry.is_file -> bool
12346 *
12347 follow_symlinks: bool = True
12348
12349Return True if the entry is a file; cached per entry.
12350[clinic start generated code]*/
12351
12352static int
12353os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12354/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012355{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012356 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012357}
12358
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012359/*[clinic input]
12360os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012361
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012362Return inode of the entry; cached per entry.
12363[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012364
12365static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012366os_DirEntry_inode_impl(DirEntry *self)
12367/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012368{
12369#ifdef MS_WINDOWS
12370 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012371 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012372 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012373 STRUCT_STAT stat;
12374 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012375
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012376 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012377 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012378 path = PyUnicode_AsUnicode(unicode);
12379 result = LSTAT(path, &stat);
12380 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012381
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012382 if (result != 0)
12383 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012384
12385 self->win32_file_index = stat.st_ino;
12386 self->got_file_index = 1;
12387 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012388 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12389 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012390#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012391 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12392 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012393#endif
12394}
12395
12396static PyObject *
12397DirEntry_repr(DirEntry *self)
12398{
12399 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12400}
12401
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012402/*[clinic input]
12403os.DirEntry.__fspath__
12404
12405Returns the path for the entry.
12406[clinic start generated code]*/
12407
Brett Cannon96881cd2016-06-10 14:37:21 -070012408static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012409os_DirEntry___fspath___impl(DirEntry *self)
12410/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012411{
12412 Py_INCREF(self->path);
12413 return self->path;
12414}
12415
Victor Stinner6036e442015-03-08 01:58:04 +010012416static PyMemberDef DirEntry_members[] = {
12417 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12418 "the entry's base filename, relative to scandir() \"path\" argument"},
12419 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12420 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12421 {NULL}
12422};
12423
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012424#include "clinic/posixmodule.c.h"
12425
Victor Stinner6036e442015-03-08 01:58:04 +010012426static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012427 OS_DIRENTRY_IS_DIR_METHODDEF
12428 OS_DIRENTRY_IS_FILE_METHODDEF
12429 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12430 OS_DIRENTRY_STAT_METHODDEF
12431 OS_DIRENTRY_INODE_METHODDEF
12432 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012433 {NULL}
12434};
12435
Benjamin Peterson5646de42015-04-12 17:56:34 -040012436static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012437 PyVarObject_HEAD_INIT(NULL, 0)
12438 MODNAME ".DirEntry", /* tp_name */
12439 sizeof(DirEntry), /* tp_basicsize */
12440 0, /* tp_itemsize */
12441 /* methods */
12442 (destructor)DirEntry_dealloc, /* tp_dealloc */
12443 0, /* tp_print */
12444 0, /* tp_getattr */
12445 0, /* tp_setattr */
12446 0, /* tp_compare */
12447 (reprfunc)DirEntry_repr, /* tp_repr */
12448 0, /* tp_as_number */
12449 0, /* tp_as_sequence */
12450 0, /* tp_as_mapping */
12451 0, /* tp_hash */
12452 0, /* tp_call */
12453 0, /* tp_str */
12454 0, /* tp_getattro */
12455 0, /* tp_setattro */
12456 0, /* tp_as_buffer */
12457 Py_TPFLAGS_DEFAULT, /* tp_flags */
12458 0, /* tp_doc */
12459 0, /* tp_traverse */
12460 0, /* tp_clear */
12461 0, /* tp_richcompare */
12462 0, /* tp_weaklistoffset */
12463 0, /* tp_iter */
12464 0, /* tp_iternext */
12465 DirEntry_methods, /* tp_methods */
12466 DirEntry_members, /* tp_members */
12467};
12468
12469#ifdef MS_WINDOWS
12470
12471static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012472join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012473{
12474 Py_ssize_t path_len;
12475 Py_ssize_t size;
12476 wchar_t *result;
12477 wchar_t ch;
12478
12479 if (!path_wide) { /* Default arg: "." */
12480 path_wide = L".";
12481 path_len = 1;
12482 }
12483 else {
12484 path_len = wcslen(path_wide);
12485 }
12486
12487 /* The +1's are for the path separator and the NUL */
12488 size = path_len + 1 + wcslen(filename) + 1;
12489 result = PyMem_New(wchar_t, size);
12490 if (!result) {
12491 PyErr_NoMemory();
12492 return NULL;
12493 }
12494 wcscpy(result, path_wide);
12495 if (path_len > 0) {
12496 ch = result[path_len - 1];
12497 if (ch != SEP && ch != ALTSEP && ch != L':')
12498 result[path_len++] = SEP;
12499 wcscpy(result + path_len, filename);
12500 }
12501 return result;
12502}
12503
12504static PyObject *
12505DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12506{
12507 DirEntry *entry;
12508 BY_HANDLE_FILE_INFORMATION file_info;
12509 ULONG reparse_tag;
12510 wchar_t *joined_path;
12511
12512 entry = PyObject_New(DirEntry, &DirEntryType);
12513 if (!entry)
12514 return NULL;
12515 entry->name = NULL;
12516 entry->path = NULL;
12517 entry->stat = NULL;
12518 entry->lstat = NULL;
12519 entry->got_file_index = 0;
12520
12521 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12522 if (!entry->name)
12523 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012524 if (path->narrow) {
12525 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12526 if (!entry->name)
12527 goto error;
12528 }
Victor Stinner6036e442015-03-08 01:58:04 +010012529
12530 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12531 if (!joined_path)
12532 goto error;
12533
12534 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12535 PyMem_Free(joined_path);
12536 if (!entry->path)
12537 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012538 if (path->narrow) {
12539 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12540 if (!entry->path)
12541 goto error;
12542 }
Victor Stinner6036e442015-03-08 01:58:04 +010012543
Steve Dowercc16be82016-09-08 10:35:16 -070012544 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012545 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12546
12547 return (PyObject *)entry;
12548
12549error:
12550 Py_DECREF(entry);
12551 return NULL;
12552}
12553
12554#else /* POSIX */
12555
12556static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012557join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012558{
12559 Py_ssize_t path_len;
12560 Py_ssize_t size;
12561 char *result;
12562
12563 if (!path_narrow) { /* Default arg: "." */
12564 path_narrow = ".";
12565 path_len = 1;
12566 }
12567 else {
12568 path_len = strlen(path_narrow);
12569 }
12570
12571 if (filename_len == -1)
12572 filename_len = strlen(filename);
12573
12574 /* The +1's are for the path separator and the NUL */
12575 size = path_len + 1 + filename_len + 1;
12576 result = PyMem_New(char, size);
12577 if (!result) {
12578 PyErr_NoMemory();
12579 return NULL;
12580 }
12581 strcpy(result, path_narrow);
12582 if (path_len > 0 && result[path_len - 1] != '/')
12583 result[path_len++] = '/';
12584 strcpy(result + path_len, filename);
12585 return result;
12586}
12587
12588static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012589DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012590 ino_t d_ino
12591#ifdef HAVE_DIRENT_D_TYPE
12592 , unsigned char d_type
12593#endif
12594 )
Victor Stinner6036e442015-03-08 01:58:04 +010012595{
12596 DirEntry *entry;
12597 char *joined_path;
12598
12599 entry = PyObject_New(DirEntry, &DirEntryType);
12600 if (!entry)
12601 return NULL;
12602 entry->name = NULL;
12603 entry->path = NULL;
12604 entry->stat = NULL;
12605 entry->lstat = NULL;
12606
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012607 if (path->fd != -1) {
12608 entry->dir_fd = path->fd;
12609 joined_path = NULL;
12610 }
12611 else {
12612 entry->dir_fd = DEFAULT_DIR_FD;
12613 joined_path = join_path_filename(path->narrow, name, name_len);
12614 if (!joined_path)
12615 goto error;
12616 }
Victor Stinner6036e442015-03-08 01:58:04 +010012617
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012618 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012619 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012620 if (joined_path)
12621 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012622 }
12623 else {
12624 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012625 if (joined_path)
12626 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012627 }
12628 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012629 if (!entry->name)
12630 goto error;
12631
12632 if (path->fd != -1) {
12633 entry->path = entry->name;
12634 Py_INCREF(entry->path);
12635 }
12636 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012637 goto error;
12638
Victor Stinner35a97c02015-03-08 02:59:09 +010012639#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012640 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012641#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012642 entry->d_ino = d_ino;
12643
12644 return (PyObject *)entry;
12645
12646error:
12647 Py_XDECREF(entry);
12648 return NULL;
12649}
12650
12651#endif
12652
12653
12654typedef struct {
12655 PyObject_HEAD
12656 path_t path;
12657#ifdef MS_WINDOWS
12658 HANDLE handle;
12659 WIN32_FIND_DATAW file_data;
12660 int first_time;
12661#else /* POSIX */
12662 DIR *dirp;
12663#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012664#ifdef HAVE_FDOPENDIR
12665 int fd;
12666#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012667} ScandirIterator;
12668
12669#ifdef MS_WINDOWS
12670
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012671static int
12672ScandirIterator_is_closed(ScandirIterator *iterator)
12673{
12674 return iterator->handle == INVALID_HANDLE_VALUE;
12675}
12676
Victor Stinner6036e442015-03-08 01:58:04 +010012677static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012678ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012679{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012680 HANDLE handle = iterator->handle;
12681
12682 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012683 return;
12684
Victor Stinner6036e442015-03-08 01:58:04 +010012685 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012686 Py_BEGIN_ALLOW_THREADS
12687 FindClose(handle);
12688 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012689}
12690
12691static PyObject *
12692ScandirIterator_iternext(ScandirIterator *iterator)
12693{
12694 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12695 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012696 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012697
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012698 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012699 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012700 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012701
12702 while (1) {
12703 if (!iterator->first_time) {
12704 Py_BEGIN_ALLOW_THREADS
12705 success = FindNextFileW(iterator->handle, file_data);
12706 Py_END_ALLOW_THREADS
12707 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012708 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012709 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012710 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012711 break;
12712 }
12713 }
12714 iterator->first_time = 0;
12715
12716 /* Skip over . and .. */
12717 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012718 wcscmp(file_data->cFileName, L"..") != 0) {
12719 entry = DirEntry_from_find_data(&iterator->path, file_data);
12720 if (!entry)
12721 break;
12722 return entry;
12723 }
Victor Stinner6036e442015-03-08 01:58:04 +010012724
12725 /* Loop till we get a non-dot directory or finish iterating */
12726 }
12727
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012728 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012729 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012730 return NULL;
12731}
12732
12733#else /* POSIX */
12734
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012735static int
12736ScandirIterator_is_closed(ScandirIterator *iterator)
12737{
12738 return !iterator->dirp;
12739}
12740
Victor Stinner6036e442015-03-08 01:58:04 +010012741static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012742ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012743{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012744 DIR *dirp = iterator->dirp;
12745
12746 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012747 return;
12748
Victor Stinner6036e442015-03-08 01:58:04 +010012749 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012750 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012751#ifdef HAVE_FDOPENDIR
12752 if (iterator->path.fd != -1)
12753 rewinddir(dirp);
12754#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012755 closedir(dirp);
12756 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012757 return;
12758}
12759
12760static PyObject *
12761ScandirIterator_iternext(ScandirIterator *iterator)
12762{
12763 struct dirent *direntp;
12764 Py_ssize_t name_len;
12765 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012766 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012767
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012768 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012769 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012770 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012771
12772 while (1) {
12773 errno = 0;
12774 Py_BEGIN_ALLOW_THREADS
12775 direntp = readdir(iterator->dirp);
12776 Py_END_ALLOW_THREADS
12777
12778 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012779 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012780 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012781 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012782 break;
12783 }
12784
12785 /* Skip over . and .. */
12786 name_len = NAMLEN(direntp);
12787 is_dot = direntp->d_name[0] == '.' &&
12788 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12789 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012790 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012791 name_len, direntp->d_ino
12792#ifdef HAVE_DIRENT_D_TYPE
12793 , direntp->d_type
12794#endif
12795 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012796 if (!entry)
12797 break;
12798 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012799 }
12800
12801 /* Loop till we get a non-dot directory or finish iterating */
12802 }
12803
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012804 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012805 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012806 return NULL;
12807}
12808
12809#endif
12810
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012811static PyObject *
12812ScandirIterator_close(ScandirIterator *self, PyObject *args)
12813{
12814 ScandirIterator_closedir(self);
12815 Py_RETURN_NONE;
12816}
12817
12818static PyObject *
12819ScandirIterator_enter(PyObject *self, PyObject *args)
12820{
12821 Py_INCREF(self);
12822 return self;
12823}
12824
12825static PyObject *
12826ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12827{
12828 ScandirIterator_closedir(self);
12829 Py_RETURN_NONE;
12830}
12831
Victor Stinner6036e442015-03-08 01:58:04 +010012832static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012833ScandirIterator_finalize(ScandirIterator *iterator)
12834{
12835 PyObject *error_type, *error_value, *error_traceback;
12836
12837 /* Save the current exception, if any. */
12838 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12839
12840 if (!ScandirIterator_is_closed(iterator)) {
12841 ScandirIterator_closedir(iterator);
12842
12843 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12844 "unclosed scandir iterator %R", iterator)) {
12845 /* Spurious errors can appear at shutdown */
12846 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12847 PyErr_WriteUnraisable((PyObject *) iterator);
12848 }
12849 }
12850 }
12851
Victor Stinner7bfa4092016-03-23 00:43:54 +010012852 path_cleanup(&iterator->path);
12853
12854 /* Restore the saved exception. */
12855 PyErr_Restore(error_type, error_value, error_traceback);
12856}
12857
12858static void
Victor Stinner6036e442015-03-08 01:58:04 +010012859ScandirIterator_dealloc(ScandirIterator *iterator)
12860{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012861 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12862 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012863
Victor Stinner6036e442015-03-08 01:58:04 +010012864 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12865}
12866
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012867static PyMethodDef ScandirIterator_methods[] = {
12868 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12869 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12870 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12871 {NULL}
12872};
12873
Benjamin Peterson5646de42015-04-12 17:56:34 -040012874static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012875 PyVarObject_HEAD_INIT(NULL, 0)
12876 MODNAME ".ScandirIterator", /* tp_name */
12877 sizeof(ScandirIterator), /* tp_basicsize */
12878 0, /* tp_itemsize */
12879 /* methods */
12880 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12881 0, /* tp_print */
12882 0, /* tp_getattr */
12883 0, /* tp_setattr */
12884 0, /* tp_compare */
12885 0, /* tp_repr */
12886 0, /* tp_as_number */
12887 0, /* tp_as_sequence */
12888 0, /* tp_as_mapping */
12889 0, /* tp_hash */
12890 0, /* tp_call */
12891 0, /* tp_str */
12892 0, /* tp_getattro */
12893 0, /* tp_setattro */
12894 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012895 Py_TPFLAGS_DEFAULT
12896 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012897 0, /* tp_doc */
12898 0, /* tp_traverse */
12899 0, /* tp_clear */
12900 0, /* tp_richcompare */
12901 0, /* tp_weaklistoffset */
12902 PyObject_SelfIter, /* tp_iter */
12903 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012904 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012905 0, /* tp_members */
12906 0, /* tp_getset */
12907 0, /* tp_base */
12908 0, /* tp_dict */
12909 0, /* tp_descr_get */
12910 0, /* tp_descr_set */
12911 0, /* tp_dictoffset */
12912 0, /* tp_init */
12913 0, /* tp_alloc */
12914 0, /* tp_new */
12915 0, /* tp_free */
12916 0, /* tp_is_gc */
12917 0, /* tp_bases */
12918 0, /* tp_mro */
12919 0, /* tp_cache */
12920 0, /* tp_subclasses */
12921 0, /* tp_weaklist */
12922 0, /* tp_del */
12923 0, /* tp_version_tag */
12924 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012925};
12926
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012927/*[clinic input]
12928os.scandir
12929
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012930 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012931
12932Return an iterator of DirEntry objects for given path.
12933
BNMetricsb9427072018-11-02 15:20:19 +000012934path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012935is bytes, the names of yielded DirEntry objects will also be bytes; in
12936all other circumstances they will be str.
12937
12938If path is None, uses the path='.'.
12939[clinic start generated code]*/
12940
Victor Stinner6036e442015-03-08 01:58:04 +010012941static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012942os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012943/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012944{
12945 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012946#ifdef MS_WINDOWS
12947 wchar_t *path_strW;
12948#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012949 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012950#ifdef HAVE_FDOPENDIR
12951 int fd = -1;
12952#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012953#endif
12954
12955 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12956 if (!iterator)
12957 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012958
12959#ifdef MS_WINDOWS
12960 iterator->handle = INVALID_HANDLE_VALUE;
12961#else
12962 iterator->dirp = NULL;
12963#endif
12964
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012965 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012966 /* Move the ownership to iterator->path */
12967 path->object = NULL;
12968 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012969
12970#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012971 iterator->first_time = 1;
12972
12973 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12974 if (!path_strW)
12975 goto error;
12976
12977 Py_BEGIN_ALLOW_THREADS
12978 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12979 Py_END_ALLOW_THREADS
12980
12981 PyMem_Free(path_strW);
12982
12983 if (iterator->handle == INVALID_HANDLE_VALUE) {
12984 path_error(&iterator->path);
12985 goto error;
12986 }
12987#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012988 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012989#ifdef HAVE_FDOPENDIR
12990 if (path->fd != -1) {
12991 /* closedir() closes the FD, so we duplicate it */
12992 fd = _Py_dup(path->fd);
12993 if (fd == -1)
12994 goto error;
12995
12996 Py_BEGIN_ALLOW_THREADS
12997 iterator->dirp = fdopendir(fd);
12998 Py_END_ALLOW_THREADS
12999 }
13000 else
13001#endif
13002 {
13003 if (iterator->path.narrow)
13004 path_str = iterator->path.narrow;
13005 else
13006 path_str = ".";
13007
13008 Py_BEGIN_ALLOW_THREADS
13009 iterator->dirp = opendir(path_str);
13010 Py_END_ALLOW_THREADS
13011 }
Victor Stinner6036e442015-03-08 01:58:04 +010013012
13013 if (!iterator->dirp) {
13014 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013015#ifdef HAVE_FDOPENDIR
13016 if (fd != -1) {
13017 Py_BEGIN_ALLOW_THREADS
13018 close(fd);
13019 Py_END_ALLOW_THREADS
13020 }
13021#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013022 goto error;
13023 }
13024#endif
13025
13026 return (PyObject *)iterator;
13027
13028error:
13029 Py_DECREF(iterator);
13030 return NULL;
13031}
13032
Ethan Furman410ef8e2016-06-04 12:06:26 -070013033/*
13034 Return the file system path representation of the object.
13035
13036 If the object is str or bytes, then allow it to pass through with
13037 an incremented refcount. If the object defines __fspath__(), then
13038 return the result of that method. All other types raise a TypeError.
13039*/
13040PyObject *
13041PyOS_FSPath(PyObject *path)
13042{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013043 /* For error message reasons, this function is manually inlined in
13044 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013045 _Py_IDENTIFIER(__fspath__);
13046 PyObject *func = NULL;
13047 PyObject *path_repr = NULL;
13048
13049 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13050 Py_INCREF(path);
13051 return path;
13052 }
13053
13054 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13055 if (NULL == func) {
13056 return PyErr_Format(PyExc_TypeError,
13057 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013058 "not %.200s",
13059 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013060 }
13061
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013062 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013063 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013064 if (NULL == path_repr) {
13065 return NULL;
13066 }
13067
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013068 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13069 PyErr_Format(PyExc_TypeError,
13070 "expected %.200s.__fspath__() to return str or bytes, "
13071 "not %.200s", Py_TYPE(path)->tp_name,
13072 Py_TYPE(path_repr)->tp_name);
13073 Py_DECREF(path_repr);
13074 return NULL;
13075 }
13076
Ethan Furman410ef8e2016-06-04 12:06:26 -070013077 return path_repr;
13078}
13079
13080/*[clinic input]
13081os.fspath
13082
13083 path: object
13084
13085Return the file system path representation of the object.
13086
Brett Cannonb4f43e92016-06-09 14:32:08 -070013087If the object is str or bytes, then allow it to pass through as-is. If the
13088object defines __fspath__(), then return the result of that method. All other
13089types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013090[clinic start generated code]*/
13091
13092static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013093os_fspath_impl(PyObject *module, PyObject *path)
13094/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013095{
13096 return PyOS_FSPath(path);
13097}
Victor Stinner6036e442015-03-08 01:58:04 +010013098
Victor Stinner9b1f4742016-09-06 16:18:52 -070013099#ifdef HAVE_GETRANDOM_SYSCALL
13100/*[clinic input]
13101os.getrandom
13102
13103 size: Py_ssize_t
13104 flags: int=0
13105
13106Obtain a series of random bytes.
13107[clinic start generated code]*/
13108
13109static PyObject *
13110os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13111/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13112{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013113 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013114 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013115
13116 if (size < 0) {
13117 errno = EINVAL;
13118 return posix_error();
13119 }
13120
Victor Stinnerec2319c2016-09-20 23:00:59 +020013121 bytes = PyBytes_FromStringAndSize(NULL, size);
13122 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013123 PyErr_NoMemory();
13124 return NULL;
13125 }
13126
13127 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013128 n = syscall(SYS_getrandom,
13129 PyBytes_AS_STRING(bytes),
13130 PyBytes_GET_SIZE(bytes),
13131 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013132 if (n < 0 && errno == EINTR) {
13133 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013134 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013135 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013136
13137 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013138 continue;
13139 }
13140 break;
13141 }
13142
13143 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013144 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013145 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013146 }
13147
Victor Stinnerec2319c2016-09-20 23:00:59 +020013148 if (n != size) {
13149 _PyBytes_Resize(&bytes, n);
13150 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013151
13152 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013153
13154error:
13155 Py_DECREF(bytes);
13156 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013157}
13158#endif /* HAVE_GETRANDOM_SYSCALL */
13159
Larry Hastings31826802013-10-19 00:09:25 -070013160
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013161static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013162
13163 OS_STAT_METHODDEF
13164 OS_ACCESS_METHODDEF
13165 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013166 OS_CHDIR_METHODDEF
13167 OS_CHFLAGS_METHODDEF
13168 OS_CHMOD_METHODDEF
13169 OS_FCHMOD_METHODDEF
13170 OS_LCHMOD_METHODDEF
13171 OS_CHOWN_METHODDEF
13172 OS_FCHOWN_METHODDEF
13173 OS_LCHOWN_METHODDEF
13174 OS_LCHFLAGS_METHODDEF
13175 OS_CHROOT_METHODDEF
13176 OS_CTERMID_METHODDEF
13177 OS_GETCWD_METHODDEF
13178 OS_GETCWDB_METHODDEF
13179 OS_LINK_METHODDEF
13180 OS_LISTDIR_METHODDEF
13181 OS_LSTAT_METHODDEF
13182 OS_MKDIR_METHODDEF
13183 OS_NICE_METHODDEF
13184 OS_GETPRIORITY_METHODDEF
13185 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013186 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013187 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013188 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013189 OS_RENAME_METHODDEF
13190 OS_REPLACE_METHODDEF
13191 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013192 OS_SYMLINK_METHODDEF
13193 OS_SYSTEM_METHODDEF
13194 OS_UMASK_METHODDEF
13195 OS_UNAME_METHODDEF
13196 OS_UNLINK_METHODDEF
13197 OS_REMOVE_METHODDEF
13198 OS_UTIME_METHODDEF
13199 OS_TIMES_METHODDEF
13200 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013201 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013202 OS_EXECV_METHODDEF
13203 OS_EXECVE_METHODDEF
13204 OS_SPAWNV_METHODDEF
13205 OS_SPAWNVE_METHODDEF
13206 OS_FORK1_METHODDEF
13207 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013208 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013209 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13210 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13211 OS_SCHED_GETPARAM_METHODDEF
13212 OS_SCHED_GETSCHEDULER_METHODDEF
13213 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13214 OS_SCHED_SETPARAM_METHODDEF
13215 OS_SCHED_SETSCHEDULER_METHODDEF
13216 OS_SCHED_YIELD_METHODDEF
13217 OS_SCHED_SETAFFINITY_METHODDEF
13218 OS_SCHED_GETAFFINITY_METHODDEF
13219 OS_OPENPTY_METHODDEF
13220 OS_FORKPTY_METHODDEF
13221 OS_GETEGID_METHODDEF
13222 OS_GETEUID_METHODDEF
13223 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013224#ifdef HAVE_GETGROUPLIST
13225 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13226#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013227 OS_GETGROUPS_METHODDEF
13228 OS_GETPID_METHODDEF
13229 OS_GETPGRP_METHODDEF
13230 OS_GETPPID_METHODDEF
13231 OS_GETUID_METHODDEF
13232 OS_GETLOGIN_METHODDEF
13233 OS_KILL_METHODDEF
13234 OS_KILLPG_METHODDEF
13235 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013236#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013237 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013238#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013239 OS_SETUID_METHODDEF
13240 OS_SETEUID_METHODDEF
13241 OS_SETREUID_METHODDEF
13242 OS_SETGID_METHODDEF
13243 OS_SETEGID_METHODDEF
13244 OS_SETREGID_METHODDEF
13245 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013246#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013247 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013248#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013249 OS_GETPGID_METHODDEF
13250 OS_SETPGRP_METHODDEF
13251 OS_WAIT_METHODDEF
13252 OS_WAIT3_METHODDEF
13253 OS_WAIT4_METHODDEF
13254 OS_WAITID_METHODDEF
13255 OS_WAITPID_METHODDEF
13256 OS_GETSID_METHODDEF
13257 OS_SETSID_METHODDEF
13258 OS_SETPGID_METHODDEF
13259 OS_TCGETPGRP_METHODDEF
13260 OS_TCSETPGRP_METHODDEF
13261 OS_OPEN_METHODDEF
13262 OS_CLOSE_METHODDEF
13263 OS_CLOSERANGE_METHODDEF
13264 OS_DEVICE_ENCODING_METHODDEF
13265 OS_DUP_METHODDEF
13266 OS_DUP2_METHODDEF
13267 OS_LOCKF_METHODDEF
13268 OS_LSEEK_METHODDEF
13269 OS_READ_METHODDEF
13270 OS_READV_METHODDEF
13271 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013272 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013273 OS_WRITE_METHODDEF
13274 OS_WRITEV_METHODDEF
13275 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013276 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013277#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013278 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013279 posix_sendfile__doc__},
13280#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013281 OS_FSTAT_METHODDEF
13282 OS_ISATTY_METHODDEF
13283 OS_PIPE_METHODDEF
13284 OS_PIPE2_METHODDEF
13285 OS_MKFIFO_METHODDEF
13286 OS_MKNOD_METHODDEF
13287 OS_MAJOR_METHODDEF
13288 OS_MINOR_METHODDEF
13289 OS_MAKEDEV_METHODDEF
13290 OS_FTRUNCATE_METHODDEF
13291 OS_TRUNCATE_METHODDEF
13292 OS_POSIX_FALLOCATE_METHODDEF
13293 OS_POSIX_FADVISE_METHODDEF
13294 OS_PUTENV_METHODDEF
13295 OS_UNSETENV_METHODDEF
13296 OS_STRERROR_METHODDEF
13297 OS_FCHDIR_METHODDEF
13298 OS_FSYNC_METHODDEF
13299 OS_SYNC_METHODDEF
13300 OS_FDATASYNC_METHODDEF
13301 OS_WCOREDUMP_METHODDEF
13302 OS_WIFCONTINUED_METHODDEF
13303 OS_WIFSTOPPED_METHODDEF
13304 OS_WIFSIGNALED_METHODDEF
13305 OS_WIFEXITED_METHODDEF
13306 OS_WEXITSTATUS_METHODDEF
13307 OS_WTERMSIG_METHODDEF
13308 OS_WSTOPSIG_METHODDEF
13309 OS_FSTATVFS_METHODDEF
13310 OS_STATVFS_METHODDEF
13311 OS_CONFSTR_METHODDEF
13312 OS_SYSCONF_METHODDEF
13313 OS_FPATHCONF_METHODDEF
13314 OS_PATHCONF_METHODDEF
13315 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013316 OS__GETFULLPATHNAME_METHODDEF
13317 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013318 OS__GETDISKUSAGE_METHODDEF
13319 OS__GETFINALPATHNAME_METHODDEF
13320 OS__GETVOLUMEPATHNAME_METHODDEF
13321 OS_GETLOADAVG_METHODDEF
13322 OS_URANDOM_METHODDEF
13323 OS_SETRESUID_METHODDEF
13324 OS_SETRESGID_METHODDEF
13325 OS_GETRESUID_METHODDEF
13326 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013327
Larry Hastings2f936352014-08-05 14:04:04 +100013328 OS_GETXATTR_METHODDEF
13329 OS_SETXATTR_METHODDEF
13330 OS_REMOVEXATTR_METHODDEF
13331 OS_LISTXATTR_METHODDEF
13332
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013333#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13334 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13335#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013336 OS_CPU_COUNT_METHODDEF
13337 OS_GET_INHERITABLE_METHODDEF
13338 OS_SET_INHERITABLE_METHODDEF
13339 OS_GET_HANDLE_INHERITABLE_METHODDEF
13340 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013341#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013342 OS_GET_BLOCKING_METHODDEF
13343 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013344#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013345 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013346 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013347 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000013348 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013349};
13350
13351
Brian Curtin52173d42010-12-02 18:29:18 +000013352#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013353static int
Brian Curtin52173d42010-12-02 18:29:18 +000013354enable_symlink()
13355{
13356 HANDLE tok;
13357 TOKEN_PRIVILEGES tok_priv;
13358 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000013359
13360 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013361 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013362
13363 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013364 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013365
13366 tok_priv.PrivilegeCount = 1;
13367 tok_priv.Privileges[0].Luid = luid;
13368 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
13369
13370 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
13371 sizeof(TOKEN_PRIVILEGES),
13372 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013373 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013374
Brian Curtin3b4499c2010-12-28 14:31:47 +000013375 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
13376 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000013377}
13378#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
13379
Barry Warsaw4a342091996-12-19 23:50:02 +000013380static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013381all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013382{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013383#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013384 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013385#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013386#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013387 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013388#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013389#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013390 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013391#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013392#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013393 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013394#endif
Fred Drakec9680921999-12-13 16:37:25 +000013395#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013396 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013397#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013398#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013399 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013400#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013401#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013402 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013403#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013404#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013405 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013406#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013407#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013408 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013409#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013410#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013411 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013412#endif
13413#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013414 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013415#endif
13416#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013417 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013418#endif
13419#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013420 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013421#endif
13422#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013423 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013424#endif
13425#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013426 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013427#endif
13428#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013429 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013430#endif
13431#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013432 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013433#endif
13434#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013435 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013436#endif
13437#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013438 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013439#endif
13440#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013441 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013442#endif
13443#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013444 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013445#endif
13446#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013447 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013448#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013449#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013450 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013451#endif
13452#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013453 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013454#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013455#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013456 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013457#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013458#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013459 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013460#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013461#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013462#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013463 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013464#endif
13465#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013466 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013467#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013468#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013469#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013470 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013471#endif
13472#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013473 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013474#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013475#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013476 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013477#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013478#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013479 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013480#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013481#ifdef O_TMPFILE
13482 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13483#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013484#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013485 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013486#endif
13487#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013488 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013489#endif
13490#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013491 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013492#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013493#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013494 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013495#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013496#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013497 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013498#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013499
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013500
Jesus Cea94363612012-06-22 18:32:07 +020013501#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013502 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013503#endif
13504#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013505 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013506#endif
13507
Tim Peters5aa91602002-01-30 05:46:57 +000013508/* MS Windows */
13509#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013510 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013511 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013512#endif
13513#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013514 /* Optimize for short life (keep in memory). */
13515 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013516 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013517#endif
13518#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013519 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013520 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013521#endif
13522#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013523 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013524 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013525#endif
13526#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013527 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013528 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013529#endif
13530
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013531/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013532#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013533 /* Send a SIGIO signal whenever input or output
13534 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013535 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013536#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013537#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013538 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013539 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013540#endif
13541#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013542 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013543 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013544#endif
13545#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013546 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013547 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013548#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013549#ifdef O_NOLINKS
13550 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013551 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013552#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013553#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013554 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013555 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013556#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013557
Victor Stinner8c62be82010-05-06 00:08:46 +000013558 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013559#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013560 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013561#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013562#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013563 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013564#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013565#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013566 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013567#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013568#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013569 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013570#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013571#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013572 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013573#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013574#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013575 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013576#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013577#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013578 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013579#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013580#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013581 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013582#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013583#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013584 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013585#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013586#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013587 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013588#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013589#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013590 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013591#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013592#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013593 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013594#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013595#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013596 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013597#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013598#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013599 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013600#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013601#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013602 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013603#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013604#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013605 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013606#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013607#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013608 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013609#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013610
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013611 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013612#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013613 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013614#endif /* ST_RDONLY */
13615#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013616 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013617#endif /* ST_NOSUID */
13618
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013619 /* GNU extensions */
13620#ifdef ST_NODEV
13621 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13622#endif /* ST_NODEV */
13623#ifdef ST_NOEXEC
13624 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13625#endif /* ST_NOEXEC */
13626#ifdef ST_SYNCHRONOUS
13627 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13628#endif /* ST_SYNCHRONOUS */
13629#ifdef ST_MANDLOCK
13630 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13631#endif /* ST_MANDLOCK */
13632#ifdef ST_WRITE
13633 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13634#endif /* ST_WRITE */
13635#ifdef ST_APPEND
13636 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13637#endif /* ST_APPEND */
13638#ifdef ST_NOATIME
13639 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13640#endif /* ST_NOATIME */
13641#ifdef ST_NODIRATIME
13642 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13643#endif /* ST_NODIRATIME */
13644#ifdef ST_RELATIME
13645 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13646#endif /* ST_RELATIME */
13647
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013648 /* FreeBSD sendfile() constants */
13649#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013650 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013651#endif
13652#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013653 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013654#endif
13655#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013656 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013657#endif
13658
Ross Lagerwall7807c352011-03-17 20:20:30 +020013659 /* constants for posix_fadvise */
13660#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013661 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013662#endif
13663#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013664 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013665#endif
13666#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013667 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013668#endif
13669#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013670 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013671#endif
13672#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013673 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013674#endif
13675#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013676 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013677#endif
13678
13679 /* constants for waitid */
13680#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013681 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13682 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13683 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013684#endif
13685#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013686 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013687#endif
13688#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013689 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013690#endif
13691#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013692 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013693#endif
13694#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013695 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013696#endif
13697#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013698 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013699#endif
13700#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013701 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013702#endif
13703#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013704 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013705#endif
13706
13707 /* constants for lockf */
13708#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013709 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013710#endif
13711#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013712 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013713#endif
13714#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013715 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013716#endif
13717#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013718 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013719#endif
13720
Pablo Galindo4defba32018-01-27 16:16:37 +000013721#ifdef RWF_DSYNC
13722 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13723#endif
13724#ifdef RWF_HIPRI
13725 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13726#endif
13727#ifdef RWF_SYNC
13728 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13729#endif
13730#ifdef RWF_NOWAIT
13731 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13732#endif
13733
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013734/* constants for posix_spawn */
13735#ifdef HAVE_POSIX_SPAWN
13736 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13737 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13738 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13739#endif
13740
Guido van Rossum246bc171999-02-01 23:54:31 +000013741#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013742 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13743 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13744 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13745 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13746 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013747#endif
13748
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013749#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013750#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013751 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013752#endif
13753#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013754 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013755#endif
13756#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013757 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013758#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013759#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013760 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013761#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013762#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013763 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013764#endif
13765#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013766 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013767#endif
13768#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013769 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013770#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013771#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013772 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013773#endif
13774#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013775 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013776#endif
13777#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013778 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013779#endif
13780#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013781 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013782#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013783#endif
13784
Benjamin Peterson9428d532011-09-14 11:45:52 -040013785#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013786 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13787 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13788 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013789#endif
13790
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013791#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013792 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013793#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013794#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013795 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013796#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013797#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013798 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013799#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013800#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013801 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013802#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013803#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013804 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013805#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013806#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013807 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013808#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013809#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013810 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013811#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013812#if HAVE_DECL_RTLD_MEMBER
13813 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13814#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013815
Victor Stinner9b1f4742016-09-06 16:18:52 -070013816#ifdef HAVE_GETRANDOM_SYSCALL
13817 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13818 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13819#endif
13820
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013821#if defined(__APPLE__)
13822 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13823#endif
13824
Victor Stinner8c62be82010-05-06 00:08:46 +000013825 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013826}
13827
13828
Martin v. Löwis1a214512008-06-11 05:26:20 +000013829static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013830 PyModuleDef_HEAD_INIT,
13831 MODNAME,
13832 posix__doc__,
13833 -1,
13834 posix_methods,
13835 NULL,
13836 NULL,
13837 NULL,
13838 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013839};
13840
13841
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013842static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013843
13844#ifdef HAVE_FACCESSAT
13845 "HAVE_FACCESSAT",
13846#endif
13847
13848#ifdef HAVE_FCHDIR
13849 "HAVE_FCHDIR",
13850#endif
13851
13852#ifdef HAVE_FCHMOD
13853 "HAVE_FCHMOD",
13854#endif
13855
13856#ifdef HAVE_FCHMODAT
13857 "HAVE_FCHMODAT",
13858#endif
13859
13860#ifdef HAVE_FCHOWN
13861 "HAVE_FCHOWN",
13862#endif
13863
Larry Hastings00964ed2013-08-12 13:49:30 -040013864#ifdef HAVE_FCHOWNAT
13865 "HAVE_FCHOWNAT",
13866#endif
13867
Larry Hastings9cf065c2012-06-22 16:30:09 -070013868#ifdef HAVE_FEXECVE
13869 "HAVE_FEXECVE",
13870#endif
13871
13872#ifdef HAVE_FDOPENDIR
13873 "HAVE_FDOPENDIR",
13874#endif
13875
Georg Brandl306336b2012-06-24 12:55:33 +020013876#ifdef HAVE_FPATHCONF
13877 "HAVE_FPATHCONF",
13878#endif
13879
Larry Hastings9cf065c2012-06-22 16:30:09 -070013880#ifdef HAVE_FSTATAT
13881 "HAVE_FSTATAT",
13882#endif
13883
13884#ifdef HAVE_FSTATVFS
13885 "HAVE_FSTATVFS",
13886#endif
13887
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013888#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013889 "HAVE_FTRUNCATE",
13890#endif
13891
Larry Hastings9cf065c2012-06-22 16:30:09 -070013892#ifdef HAVE_FUTIMENS
13893 "HAVE_FUTIMENS",
13894#endif
13895
13896#ifdef HAVE_FUTIMES
13897 "HAVE_FUTIMES",
13898#endif
13899
13900#ifdef HAVE_FUTIMESAT
13901 "HAVE_FUTIMESAT",
13902#endif
13903
13904#ifdef HAVE_LINKAT
13905 "HAVE_LINKAT",
13906#endif
13907
13908#ifdef HAVE_LCHFLAGS
13909 "HAVE_LCHFLAGS",
13910#endif
13911
13912#ifdef HAVE_LCHMOD
13913 "HAVE_LCHMOD",
13914#endif
13915
13916#ifdef HAVE_LCHOWN
13917 "HAVE_LCHOWN",
13918#endif
13919
13920#ifdef HAVE_LSTAT
13921 "HAVE_LSTAT",
13922#endif
13923
13924#ifdef HAVE_LUTIMES
13925 "HAVE_LUTIMES",
13926#endif
13927
13928#ifdef HAVE_MKDIRAT
13929 "HAVE_MKDIRAT",
13930#endif
13931
13932#ifdef HAVE_MKFIFOAT
13933 "HAVE_MKFIFOAT",
13934#endif
13935
13936#ifdef HAVE_MKNODAT
13937 "HAVE_MKNODAT",
13938#endif
13939
13940#ifdef HAVE_OPENAT
13941 "HAVE_OPENAT",
13942#endif
13943
13944#ifdef HAVE_READLINKAT
13945 "HAVE_READLINKAT",
13946#endif
13947
13948#ifdef HAVE_RENAMEAT
13949 "HAVE_RENAMEAT",
13950#endif
13951
13952#ifdef HAVE_SYMLINKAT
13953 "HAVE_SYMLINKAT",
13954#endif
13955
13956#ifdef HAVE_UNLINKAT
13957 "HAVE_UNLINKAT",
13958#endif
13959
13960#ifdef HAVE_UTIMENSAT
13961 "HAVE_UTIMENSAT",
13962#endif
13963
13964#ifdef MS_WINDOWS
13965 "MS_WINDOWS",
13966#endif
13967
13968 NULL
13969};
13970
13971
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013972PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013973INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013974{
Victor Stinner8c62be82010-05-06 00:08:46 +000013975 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013976 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013977 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013978
Brian Curtin52173d42010-12-02 18:29:18 +000013979#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013980 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013981#endif
13982
Victor Stinner8c62be82010-05-06 00:08:46 +000013983 m = PyModule_Create(&posixmodule);
13984 if (m == NULL)
13985 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013986
Victor Stinner8c62be82010-05-06 00:08:46 +000013987 /* Initialize environ dictionary */
13988 v = convertenviron();
13989 Py_XINCREF(v);
13990 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13991 return NULL;
13992 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013993
Victor Stinner8c62be82010-05-06 00:08:46 +000013994 if (all_ins(m))
13995 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013996
Victor Stinner8c62be82010-05-06 00:08:46 +000013997 if (setup_confname_tables(m))
13998 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013999
Victor Stinner8c62be82010-05-06 00:08:46 +000014000 Py_INCREF(PyExc_OSError);
14001 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014002
Guido van Rossumb3d39562000-01-31 18:41:26 +000014003#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014004 if (posix_putenv_garbage == NULL)
14005 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014006#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014007
Victor Stinner8c62be82010-05-06 00:08:46 +000014008 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014009#if defined(HAVE_WAITID) && !defined(__APPLE__)
14010 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014011 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14012 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014013 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014014 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014015#endif
14016
Christian Heimes25827622013-10-12 01:27:08 +020014017 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014018 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14019 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14020 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014021 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14022 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014023 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014024 }
14025 structseq_new = StatResultType->tp_new;
14026 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014027
Christian Heimes25827622013-10-12 01:27:08 +020014028 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014029 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14030 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014031 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014032 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014033#ifdef NEED_TICKS_PER_SECOND
14034# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014035 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014036# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014037 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014038# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014039 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014040# endif
14041#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014042
William Orr81574b82018-10-01 22:19:56 -070014043#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014044 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014045 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14046 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014047 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014048 }
14049 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014050#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014051
14052 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014053 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14054 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014055 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014056 }
Victor Stinner6036e442015-03-08 01:58:04 +010014057
14058 /* initialize scandir types */
14059 if (PyType_Ready(&ScandirIteratorType) < 0)
14060 return NULL;
14061 if (PyType_Ready(&DirEntryType) < 0)
14062 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014063 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014064#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014065 Py_INCREF((PyObject*) WaitidResultType);
14066 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014067#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014068 Py_INCREF((PyObject*) StatResultType);
14069 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14070 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014071 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014072 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014073
14074#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014075 Py_INCREF(SchedParamType);
14076 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014077#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014078
Larry Hastings605a62d2012-06-24 04:33:36 -070014079 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014080 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14081 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014082 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014083 }
14084 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014085
14086 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014087 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14088 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014089 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014090 }
14091 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014092
Thomas Wouters477c8d52006-05-27 19:21:47 +000014093#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014094 /*
14095 * Step 2 of weak-linking support on Mac OS X.
14096 *
14097 * The code below removes functions that are not available on the
14098 * currently active platform.
14099 *
14100 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014101 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014102 * OSX 10.4.
14103 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014104#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014105 if (fstatvfs == NULL) {
14106 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14107 return NULL;
14108 }
14109 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014110#endif /* HAVE_FSTATVFS */
14111
14112#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014113 if (statvfs == NULL) {
14114 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14115 return NULL;
14116 }
14117 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014118#endif /* HAVE_STATVFS */
14119
14120# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014121 if (lchown == NULL) {
14122 if (PyObject_DelAttrString(m, "lchown") == -1) {
14123 return NULL;
14124 }
14125 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014126#endif /* HAVE_LCHOWN */
14127
14128
14129#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014130
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014131 Py_INCREF(TerminalSizeType);
14132 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014133
Larry Hastings6fe20b32012-04-19 15:07:49 -070014134 billion = PyLong_FromLong(1000000000);
14135 if (!billion)
14136 return NULL;
14137
Larry Hastings9cf065c2012-06-22 16:30:09 -070014138 /* suppress "function not used" warnings */
14139 {
14140 int ignored;
14141 fd_specified("", -1);
14142 follow_symlinks_specified("", 1);
14143 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14144 dir_fd_converter(Py_None, &ignored);
14145 dir_fd_unavailable(Py_None, &ignored);
14146 }
14147
14148 /*
14149 * provide list of locally available functions
14150 * so os.py can populate support_* lists
14151 */
14152 list = PyList_New(0);
14153 if (!list)
14154 return NULL;
14155 for (trace = have_functions; *trace; trace++) {
14156 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14157 if (!unicode)
14158 return NULL;
14159 if (PyList_Append(list, unicode))
14160 return NULL;
14161 Py_DECREF(unicode);
14162 }
14163 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014164
14165 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014166 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014167
14168 initialized = 1;
14169
Victor Stinner8c62be82010-05-06 00:08:46 +000014170 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014171}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014172
14173#ifdef __cplusplus
14174}
14175#endif