blob: d05724a50d1c4c6f65b714b59a2f5365e555d724 [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
370#ifdef HAVE_FORK
371static void
372run_at_forkers(PyObject *lst, int reverse)
373{
374 Py_ssize_t i;
375 PyObject *cpy;
376
377 if (lst != NULL) {
378 assert(PyList_CheckExact(lst));
379
380 /* Use a list copy in case register_at_fork() is called from
381 * one of the callbacks.
382 */
383 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
384 if (cpy == NULL)
385 PyErr_WriteUnraisable(lst);
386 else {
387 if (reverse)
388 PyList_Reverse(cpy);
389 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
390 PyObject *func, *res;
391 func = PyList_GET_ITEM(cpy, i);
392 res = PyObject_CallObject(func, NULL);
393 if (res == NULL)
394 PyErr_WriteUnraisable(func);
395 else
396 Py_DECREF(res);
397 }
398 Py_DECREF(cpy);
399 }
400 }
401}
402
403void
404PyOS_BeforeFork(void)
405{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200406 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200407
408 _PyImport_AcquireLock();
409}
410
411void
412PyOS_AfterFork_Parent(void)
413{
414 if (_PyImport_ReleaseLock() <= 0)
415 Py_FatalError("failed releasing import lock after fork");
416
Victor Stinnercaba55b2018-08-03 15:33:52 +0200417 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200418}
419
420void
421PyOS_AfterFork_Child(void)
422{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200423 _PyGILState_Reinit();
Eric Snow59032962018-09-14 14:17:20 -0700424 _PyInterpreterState_DeleteExceptMain();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200425 PyEval_ReInitThreads();
426 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200427 _PySignal_AfterFork();
428
Victor Stinnercaba55b2018-08-03 15:33:52 +0200429 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200430}
431
432static int
433register_at_forker(PyObject **lst, PyObject *func)
434{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700435 if (func == NULL) /* nothing to register? do nothing. */
436 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200437 if (*lst == NULL) {
438 *lst = PyList_New(0);
439 if (*lst == NULL)
440 return -1;
441 }
442 return PyList_Append(*lst, func);
443}
444#endif
445
446/* Legacy wrapper */
447void
448PyOS_AfterFork(void)
449{
450#ifdef HAVE_FORK
451 PyOS_AfterFork_Child();
452#endif
453}
454
455
Victor Stinner6036e442015-03-08 01:58:04 +0100456#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200457/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700458void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
459void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200460 ULONG, struct _Py_stat_struct *);
461#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700462
463#ifdef MS_WINDOWS
464static int
465win32_warn_bytes_api()
466{
467 return PyErr_WarnEx(PyExc_DeprecationWarning,
468 "The Windows bytes API has been deprecated, "
469 "use Unicode filenames instead",
470 1);
471}
472#endif
473
474
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200475#ifndef MS_WINDOWS
476PyObject *
477_PyLong_FromUid(uid_t uid)
478{
479 if (uid == (uid_t)-1)
480 return PyLong_FromLong(-1);
481 return PyLong_FromUnsignedLong(uid);
482}
483
484PyObject *
485_PyLong_FromGid(gid_t gid)
486{
487 if (gid == (gid_t)-1)
488 return PyLong_FromLong(-1);
489 return PyLong_FromUnsignedLong(gid);
490}
491
492int
493_Py_Uid_Converter(PyObject *obj, void *p)
494{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700495 uid_t uid;
496 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200497 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200498 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700499 unsigned long uresult;
500
501 index = PyNumber_Index(obj);
502 if (index == NULL) {
503 PyErr_Format(PyExc_TypeError,
504 "uid should be integer, not %.200s",
505 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200506 return 0;
507 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700508
509 /*
510 * Handling uid_t is complicated for two reasons:
511 * * Although uid_t is (always?) unsigned, it still
512 * accepts -1.
513 * * We don't know its size in advance--it may be
514 * bigger than an int, or it may be smaller than
515 * a long.
516 *
517 * So a bit of defensive programming is in order.
518 * Start with interpreting the value passed
519 * in as a signed long and see if it works.
520 */
521
522 result = PyLong_AsLongAndOverflow(index, &overflow);
523
524 if (!overflow) {
525 uid = (uid_t)result;
526
527 if (result == -1) {
528 if (PyErr_Occurred())
529 goto fail;
530 /* It's a legitimate -1, we're done. */
531 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /* Any other negative number is disallowed. */
535 if (result < 0)
536 goto underflow;
537
538 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200539 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700540 (long)uid != result)
541 goto underflow;
542 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200543 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700544
545 if (overflow < 0)
546 goto underflow;
547
548 /*
549 * Okay, the value overflowed a signed long. If it
550 * fits in an *unsigned* long, it may still be okay,
551 * as uid_t may be unsigned long on this platform.
552 */
553 uresult = PyLong_AsUnsignedLong(index);
554 if (PyErr_Occurred()) {
555 if (PyErr_ExceptionMatches(PyExc_OverflowError))
556 goto overflow;
557 goto fail;
558 }
559
560 uid = (uid_t)uresult;
561
562 /*
563 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
564 * but this value would get interpreted as (uid_t)-1 by chown
565 * and its siblings. That's not what the user meant! So we
566 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100567 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700568 */
569 if (uid == (uid_t)-1)
570 goto overflow;
571
572 /* Ensure the value wasn't truncated. */
573 if (sizeof(uid_t) < sizeof(long) &&
574 (unsigned long)uid != uresult)
575 goto overflow;
576 /* fallthrough */
577
578success:
579 Py_DECREF(index);
580 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200581 return 1;
582
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700583underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200584 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700585 "uid is less than minimum");
586 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200587
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700588overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200589 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700590 "uid is greater than maximum");
591 /* fallthrough */
592
593fail:
594 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200595 return 0;
596}
597
598int
599_Py_Gid_Converter(PyObject *obj, void *p)
600{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700601 gid_t gid;
602 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200603 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200604 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700605 unsigned long uresult;
606
607 index = PyNumber_Index(obj);
608 if (index == NULL) {
609 PyErr_Format(PyExc_TypeError,
610 "gid should be integer, not %.200s",
611 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200612 return 0;
613 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614
615 /*
616 * Handling gid_t is complicated for two reasons:
617 * * Although gid_t is (always?) unsigned, it still
618 * accepts -1.
619 * * We don't know its size in advance--it may be
620 * bigger than an int, or it may be smaller than
621 * a long.
622 *
623 * So a bit of defensive programming is in order.
624 * Start with interpreting the value passed
625 * in as a signed long and see if it works.
626 */
627
628 result = PyLong_AsLongAndOverflow(index, &overflow);
629
630 if (!overflow) {
631 gid = (gid_t)result;
632
633 if (result == -1) {
634 if (PyErr_Occurred())
635 goto fail;
636 /* It's a legitimate -1, we're done. */
637 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200638 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700639
640 /* Any other negative number is disallowed. */
641 if (result < 0) {
642 goto underflow;
643 }
644
645 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200646 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647 (long)gid != result)
648 goto underflow;
649 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200650 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700651
652 if (overflow < 0)
653 goto underflow;
654
655 /*
656 * Okay, the value overflowed a signed long. If it
657 * fits in an *unsigned* long, it may still be okay,
658 * as gid_t may be unsigned long on this platform.
659 */
660 uresult = PyLong_AsUnsignedLong(index);
661 if (PyErr_Occurred()) {
662 if (PyErr_ExceptionMatches(PyExc_OverflowError))
663 goto overflow;
664 goto fail;
665 }
666
667 gid = (gid_t)uresult;
668
669 /*
670 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
671 * but this value would get interpreted as (gid_t)-1 by chown
672 * and its siblings. That's not what the user meant! So we
673 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100674 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675 */
676 if (gid == (gid_t)-1)
677 goto overflow;
678
679 /* Ensure the value wasn't truncated. */
680 if (sizeof(gid_t) < sizeof(long) &&
681 (unsigned long)gid != uresult)
682 goto overflow;
683 /* fallthrough */
684
685success:
686 Py_DECREF(index);
687 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200688 return 1;
689
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200691 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 "gid is less than minimum");
693 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200694
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700695overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200696 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697 "gid is greater than maximum");
698 /* fallthrough */
699
700fail:
701 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200702 return 0;
703}
704#endif /* MS_WINDOWS */
705
706
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700707#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800708
709
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200710#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
711static int
712_Py_Dev_Converter(PyObject *obj, void *p)
713{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200714 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200715 if (PyErr_Occurred())
716 return 0;
717 return 1;
718}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800719#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200720
721
Larry Hastings9cf065c2012-06-22 16:30:09 -0700722#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400723/*
724 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
725 * without the int cast, the value gets interpreted as uint (4291925331),
726 * which doesn't play nicely with all the initializer lines in this file that
727 * look like this:
728 * int dir_fd = DEFAULT_DIR_FD;
729 */
730#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700731#else
732#define DEFAULT_DIR_FD (-100)
733#endif
734
735static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300736_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200737{
738 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700739 long long_value;
740
741 PyObject *index = PyNumber_Index(o);
742 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700743 return 0;
744 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700745
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300746 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700747 long_value = PyLong_AsLongAndOverflow(index, &overflow);
748 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300749 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200750 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700751 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700752 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700753 return 0;
754 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200755 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700756 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700757 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700758 return 0;
759 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700760
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761 *p = (int)long_value;
762 return 1;
763}
764
765static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200766dir_fd_converter(PyObject *o, void *p)
767{
768 if (o == Py_None) {
769 *(int *)p = DEFAULT_DIR_FD;
770 return 1;
771 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300772 else if (PyIndex_Check(o)) {
773 return _fd_converter(o, (int *)p);
774 }
775 else {
776 PyErr_Format(PyExc_TypeError,
777 "argument should be integer or None, not %.200s",
778 Py_TYPE(o)->tp_name);
779 return 0;
780 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781}
782
783
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784/*
785 * A PyArg_ParseTuple "converter" function
786 * that handles filesystem paths in the manner
787 * preferred by the os module.
788 *
789 * path_converter accepts (Unicode) strings and their
790 * subclasses, and bytes and their subclasses. What
791 * it does with the argument depends on the platform:
792 *
793 * * On Windows, if we get a (Unicode) string we
794 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700795 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700796 *
797 * * On all other platforms, strings are encoded
798 * to bytes using PyUnicode_FSConverter, then we
799 * extract the char * from the bytes object and
800 * return that.
801 *
802 * path_converter also optionally accepts signed
803 * integers (representing open file descriptors) instead
804 * of path strings.
805 *
806 * Input fields:
807 * path.nullable
808 * If nonzero, the path is permitted to be None.
809 * path.allow_fd
810 * If nonzero, the path is permitted to be a file handle
811 * (a signed int) instead of a string.
812 * path.function_name
813 * If non-NULL, path_converter will use that as the name
814 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700815 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816 * path.argument_name
817 * If non-NULL, path_converter will use that as the name
818 * of the parameter in error messages.
819 * (If path.argument_name is NULL it uses "path".)
820 *
821 * Output fields:
822 * path.wide
823 * Points to the path if it was expressed as Unicode
824 * and was not encoded. (Only used on Windows.)
825 * path.narrow
826 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700827 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000828 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700829 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700830 * path.fd
831 * Contains a file descriptor if path.accept_fd was true
832 * and the caller provided a signed integer instead of any
833 * sort of string.
834 *
835 * WARNING: if your "path" parameter is optional, and is
836 * unspecified, path_converter will never get called.
837 * So if you set allow_fd, you *MUST* initialize path.fd = -1
838 * yourself!
839 * path.length
840 * The length of the path in characters, if specified as
841 * a string.
842 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800843 * The original object passed in (if get a PathLike object,
844 * the result of PyOS_FSPath() is treated as the original object).
845 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700846 * path.cleanup
847 * For internal use only. May point to a temporary object.
848 * (Pay no attention to the man behind the curtain.)
849 *
850 * At most one of path.wide or path.narrow will be non-NULL.
851 * If path was None and path.nullable was set,
852 * or if path was an integer and path.allow_fd was set,
853 * both path.wide and path.narrow will be NULL
854 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200855 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700856 * path_converter takes care to not write to the path_t
857 * unless it's successful. However it must reset the
858 * "cleanup" field each time it's called.
859 *
860 * Use as follows:
861 * path_t path;
862 * memset(&path, 0, sizeof(path));
863 * PyArg_ParseTuple(args, "O&", path_converter, &path);
864 * // ... use values from path ...
865 * path_cleanup(&path);
866 *
867 * (Note that if PyArg_Parse fails you don't need to call
868 * path_cleanup(). However it is safe to do so.)
869 */
870typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100871 const char *function_name;
872 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873 int nullable;
874 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300875 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700876#ifdef MS_WINDOWS
877 BOOL narrow;
878#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300879 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700880#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881 int fd;
882 Py_ssize_t length;
883 PyObject *object;
884 PyObject *cleanup;
885} path_t;
886
Steve Dowercc16be82016-09-08 10:35:16 -0700887#ifdef MS_WINDOWS
888#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
889 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
890#else
Larry Hastings2f936352014-08-05 14:04:04 +1000891#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
892 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700893#endif
Larry Hastings31826802013-10-19 00:09:25 -0700894
Larry Hastings9cf065c2012-06-22 16:30:09 -0700895static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800896path_cleanup(path_t *path)
897{
898 Py_CLEAR(path->object);
899 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700900}
901
902static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300903path_converter(PyObject *o, void *p)
904{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700905 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800906 PyObject *bytes = NULL;
907 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700908 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300909 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700910#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800911 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700912 const wchar_t *wide;
913#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700914
915#define FORMAT_EXCEPTION(exc, fmt) \
916 PyErr_Format(exc, "%s%s" fmt, \
917 path->function_name ? path->function_name : "", \
918 path->function_name ? ": " : "", \
919 path->argument_name ? path->argument_name : "path")
920
921 /* Py_CLEANUP_SUPPORTED support */
922 if (o == NULL) {
923 path_cleanup(path);
924 return 1;
925 }
926
Brett Cannon3f9183b2016-08-26 14:44:48 -0700927 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800928 path->object = path->cleanup = NULL;
929 /* path->object owns a reference to the original object */
930 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300932 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700934#ifdef MS_WINDOWS
935 path->narrow = FALSE;
936#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700938#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800940 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 }
942
Brett Cannon3f9183b2016-08-26 14:44:48 -0700943 /* Only call this here so that we don't treat the return value of
944 os.fspath() as an fd or buffer. */
945 is_index = path->allow_fd && PyIndex_Check(o);
946 is_buffer = PyObject_CheckBuffer(o);
947 is_bytes = PyBytes_Check(o);
948 is_unicode = PyUnicode_Check(o);
949
950 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
951 /* Inline PyOS_FSPath() for better error messages. */
952 _Py_IDENTIFIER(__fspath__);
953 PyObject *func = NULL;
954
955 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
956 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800957 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700958 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800959 /* still owns a reference to the original object */
960 Py_DECREF(o);
961 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700962 Py_DECREF(func);
963 if (NULL == o) {
964 goto error_exit;
965 }
966 else if (PyUnicode_Check(o)) {
967 is_unicode = 1;
968 }
969 else if (PyBytes_Check(o)) {
970 is_bytes = 1;
971 }
972 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800973 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700974 }
975 }
976
977 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +0200979 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100980 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800981 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700982 }
Victor Stinner59799a82013-11-13 14:17:30 +0100983 if (length > 32767) {
984 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +0800985 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700986 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300987 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300988 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +0800989 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300990 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991
992 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +0800993 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700994 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800995 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700996#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300997 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800998 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300999 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001000#endif
1001 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001002 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001003 bytes = o;
1004 Py_INCREF(bytes);
1005 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001006 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001007 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001008 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001009 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1010 "%s%s%s should be %s, not %.200s",
1011 path->function_name ? path->function_name : "",
1012 path->function_name ? ": " : "",
1013 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001014 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1015 "integer or None" :
1016 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1017 path->nullable ? "string, bytes, os.PathLike or None" :
1018 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001019 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001021 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001022 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001023 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001024 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025 }
1026 }
Steve Dowercc16be82016-09-08 10:35:16 -07001027 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001028 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001029 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001030 }
1031 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001032#ifdef MS_WINDOWS
1033 path->narrow = FALSE;
1034#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001035 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001036#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001037 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001038 }
1039 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001040 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001041 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1042 path->function_name ? path->function_name : "",
1043 path->function_name ? ": " : "",
1044 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001045 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1046 "integer or None" :
1047 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1048 path->nullable ? "string, bytes, os.PathLike or None" :
1049 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001050 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 }
1053
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001056 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001057 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001058 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059 }
1060
Steve Dowercc16be82016-09-08 10:35:16 -07001061#ifdef MS_WINDOWS
1062 wo = PyUnicode_DecodeFSDefaultAndSize(
1063 narrow,
1064 length
1065 );
1066 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001067 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001068 }
1069
Xiang Zhang04316c42017-01-08 23:26:57 +08001070 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001071 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001072 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001073 }
1074 if (length > 32767) {
1075 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001077 }
1078 if (wcslen(wide) != length) {
1079 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001080 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001081 }
1082 path->wide = wide;
1083 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001084 path->cleanup = wo;
1085 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001086#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001087 path->wide = NULL;
1088 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001089 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001090 /* Still a reference owned by path->object, don't have to
1091 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001092 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001093 }
1094 else {
1095 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001096 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001097#endif
1098 path->fd = -1;
1099
1100 success_exit:
1101 path->length = length;
1102 path->object = o;
1103 return Py_CLEANUP_SUPPORTED;
1104
1105 error_exit:
1106 Py_XDECREF(o);
1107 Py_XDECREF(bytes);
1108#ifdef MS_WINDOWS
1109 Py_XDECREF(wo);
1110#endif
1111 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001112}
1113
1114static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001115argument_unavailable_error(const char *function_name, const char *argument_name)
1116{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001117 PyErr_Format(PyExc_NotImplementedError,
1118 "%s%s%s unavailable on this platform",
1119 (function_name != NULL) ? function_name : "",
1120 (function_name != NULL) ? ": ": "",
1121 argument_name);
1122}
1123
1124static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001125dir_fd_unavailable(PyObject *o, void *p)
1126{
1127 int dir_fd;
1128 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001130 if (dir_fd != DEFAULT_DIR_FD) {
1131 argument_unavailable_error(NULL, "dir_fd");
1132 return 0;
1133 }
1134 *(int *)p = dir_fd;
1135 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001136}
1137
1138static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001139fd_specified(const char *function_name, int fd)
1140{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141 if (fd == -1)
1142 return 0;
1143
1144 argument_unavailable_error(function_name, "fd");
1145 return 1;
1146}
1147
1148static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001149follow_symlinks_specified(const char *function_name, int follow_symlinks)
1150{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001151 if (follow_symlinks)
1152 return 0;
1153
1154 argument_unavailable_error(function_name, "follow_symlinks");
1155 return 1;
1156}
1157
1158static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001159path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1160{
Steve Dowercc16be82016-09-08 10:35:16 -07001161 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1162#ifndef MS_WINDOWS
1163 && !path->narrow
1164#endif
1165 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001166 PyErr_Format(PyExc_ValueError,
1167 "%s: can't specify dir_fd without matching path",
1168 function_name);
1169 return 1;
1170 }
1171 return 0;
1172}
1173
1174static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001175dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1176{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1178 PyErr_Format(PyExc_ValueError,
1179 "%s: can't specify both dir_fd and fd",
1180 function_name);
1181 return 1;
1182 }
1183 return 0;
1184}
1185
1186static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001187fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1188 int follow_symlinks)
1189{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001190 if ((fd > 0) && (!follow_symlinks)) {
1191 PyErr_Format(PyExc_ValueError,
1192 "%s: cannot use fd and follow_symlinks together",
1193 function_name);
1194 return 1;
1195 }
1196 return 0;
1197}
1198
1199static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001200dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1201 int follow_symlinks)
1202{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001203 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1204 PyErr_Format(PyExc_ValueError,
1205 "%s: cannot use dir_fd and follow_symlinks together",
1206 function_name);
1207 return 1;
1208 }
1209 return 0;
1210}
1211
Larry Hastings2f936352014-08-05 14:04:04 +10001212#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001213 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001214#else
Larry Hastings2f936352014-08-05 14:04:04 +10001215 typedef off_t Py_off_t;
1216#endif
1217
1218static int
1219Py_off_t_converter(PyObject *arg, void *addr)
1220{
1221#ifdef HAVE_LARGEFILE_SUPPORT
1222 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1223#else
1224 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001225#endif
1226 if (PyErr_Occurred())
1227 return 0;
1228 return 1;
1229}
Larry Hastings2f936352014-08-05 14:04:04 +10001230
1231static PyObject *
1232PyLong_FromPy_off_t(Py_off_t offset)
1233{
1234#ifdef HAVE_LARGEFILE_SUPPORT
1235 return PyLong_FromLongLong(offset);
1236#else
1237 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001238#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001239}
1240
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001241#ifdef HAVE_SIGSET_T
1242/* Convert an iterable of integers to a sigset.
1243 Return 1 on success, return 0 and raise an exception on error. */
1244int
1245_Py_Sigset_Converter(PyObject *obj, void *addr)
1246{
1247 sigset_t *mask = (sigset_t *)addr;
1248 PyObject *iterator, *item;
1249 long signum;
1250 int overflow;
1251
1252 if (sigemptyset(mask)) {
1253 /* Probably only if mask == NULL. */
1254 PyErr_SetFromErrno(PyExc_OSError);
1255 return 0;
1256 }
1257
1258 iterator = PyObject_GetIter(obj);
1259 if (iterator == NULL) {
1260 return 0;
1261 }
1262
1263 while ((item = PyIter_Next(iterator)) != NULL) {
1264 signum = PyLong_AsLongAndOverflow(item, &overflow);
1265 Py_DECREF(item);
1266 if (signum <= 0 || signum >= NSIG) {
1267 if (overflow || signum != -1 || !PyErr_Occurred()) {
1268 PyErr_Format(PyExc_ValueError,
1269 "signal number %ld out of range", signum);
1270 }
1271 goto error;
1272 }
1273 if (sigaddset(mask, (int)signum)) {
1274 if (errno != EINVAL) {
1275 /* Probably impossible */
1276 PyErr_SetFromErrno(PyExc_OSError);
1277 goto error;
1278 }
1279 /* For backwards compatibility, allow idioms such as
1280 * `range(1, NSIG)` but warn about invalid signal numbers
1281 */
1282 const char msg[] =
1283 "invalid signal number %ld, please use valid_signals()";
1284 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1285 goto error;
1286 }
1287 }
1288 }
1289 if (!PyErr_Occurred()) {
1290 Py_DECREF(iterator);
1291 return 1;
1292 }
1293
1294error:
1295 Py_DECREF(iterator);
1296 return 0;
1297}
1298#endif /* HAVE_SIGSET_T */
1299
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001300#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001301
1302static int
Brian Curtind25aef52011-06-13 15:16:04 -05001303win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001304{
Martin Panter70214ad2016-08-04 02:38:59 +00001305 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1306 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001307 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001308
1309 if (0 == DeviceIoControl(
1310 reparse_point_handle,
1311 FSCTL_GET_REPARSE_POINT,
1312 NULL, 0, /* in buffer */
1313 target_buffer, sizeof(target_buffer),
1314 &n_bytes_returned,
1315 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001316 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001317
1318 if (reparse_tag)
1319 *reparse_tag = rdb->ReparseTag;
1320
Brian Curtind25aef52011-06-13 15:16:04 -05001321 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001322}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001323
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001324#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001325
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001327#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001328/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001329** environ directly, we must obtain it with _NSGetEnviron(). See also
1330** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001331*/
1332#include <crt_externs.h>
1333static char **environ;
1334#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001335extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001336#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337
Barry Warsaw53699e91996-12-10 23:23:01 +00001338static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001339convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340{
Victor Stinner8c62be82010-05-06 00:08:46 +00001341 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001342#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001344#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001346#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001347
Victor Stinner8c62be82010-05-06 00:08:46 +00001348 d = PyDict_New();
1349 if (d == NULL)
1350 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001351#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 if (environ == NULL)
1353 environ = *_NSGetEnviron();
1354#endif
1355#ifdef MS_WINDOWS
1356 /* _wenviron must be initialized in this way if the program is started
1357 through main() instead of wmain(). */
1358 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001359 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001360#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001361 e = environ;
1362#endif
1363 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001365 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 PyObject *k;
1367 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001368#ifdef MS_WINDOWS
1369 const wchar_t *p = wcschr(*e, L'=');
1370#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001371 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001372#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001373 if (p == NULL)
1374 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001375#ifdef MS_WINDOWS
1376 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1377#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001378 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001379#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001381 Py_DECREF(d);
1382 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001384#ifdef MS_WINDOWS
1385 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1386#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001387 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001388#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001390 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001391 Py_DECREF(d);
1392 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001394 if (PyDict_GetItemWithError(d, k) == NULL) {
1395 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1396 Py_DECREF(v);
1397 Py_DECREF(k);
1398 Py_DECREF(d);
1399 return NULL;
1400 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 }
1402 Py_DECREF(k);
1403 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001404 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001405 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001406}
1407
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001408/* Set a POSIX-specific error from errno, and return NULL */
1409
Barry Warsawd58d7641998-07-23 16:14:40 +00001410static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001411posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001412{
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001414}
Mark Hammondef8b6542001-05-13 08:04:26 +00001415
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001416#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001417static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001418win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001419{
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 /* XXX We should pass the function name along in the future.
1421 (winreg.c also wants to pass the function name.)
1422 This would however require an additional param to the
1423 Windows error object, which is non-trivial.
1424 */
1425 errno = GetLastError();
1426 if (filename)
1427 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1428 else
1429 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001430}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001431
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001432static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001433win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001434{
1435 /* XXX - see win32_error for comments on 'function' */
1436 errno = GetLastError();
1437 if (filename)
1438 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001439 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001440 errno,
1441 filename);
1442 else
1443 return PyErr_SetFromWindowsErr(errno);
1444}
1445
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001446#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001447
Larry Hastings9cf065c2012-06-22 16:30:09 -07001448static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001449posix_path_object_error(PyObject *path)
1450{
1451 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1452}
1453
1454static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001455path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001456{
1457#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001458 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1459 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001460#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001461 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001462#endif
1463}
1464
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001465static PyObject *
1466path_object_error2(PyObject *path, PyObject *path2)
1467{
1468#ifdef MS_WINDOWS
1469 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1470 PyExc_OSError, 0, path, path2);
1471#else
1472 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1473#endif
1474}
1475
1476static PyObject *
1477path_error(path_t *path)
1478{
1479 return path_object_error(path->object);
1480}
Larry Hastings31826802013-10-19 00:09:25 -07001481
Larry Hastingsb0827312014-02-09 22:05:19 -08001482static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001483posix_path_error(path_t *path)
1484{
1485 return posix_path_object_error(path->object);
1486}
1487
1488static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001489path_error2(path_t *path, path_t *path2)
1490{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001491 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001492}
1493
1494
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001495/* POSIX generic methods */
1496
Larry Hastings2f936352014-08-05 14:04:04 +10001497static int
1498fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001499{
Victor Stinner8c62be82010-05-06 00:08:46 +00001500 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001501 int *pointer = (int *)p;
1502 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001503 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001504 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001505 *pointer = fd;
1506 return 1;
1507}
1508
1509static PyObject *
1510posix_fildes_fd(int fd, int (*func)(int))
1511{
1512 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001513 int async_err = 0;
1514
1515 do {
1516 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001517 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001518 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001519 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001520 Py_END_ALLOW_THREADS
1521 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1522 if (res != 0)
1523 return (!async_err) ? posix_error() : NULL;
1524 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001525}
Guido van Rossum21142a01999-01-08 21:05:37 +00001526
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001527
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001528#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001529/* This is a reimplementation of the C library's chdir function,
1530 but one that produces Win32 errors instead of DOS error codes.
1531 chdir is essentially a wrapper around SetCurrentDirectory; however,
1532 it also needs to set "magic" environment variables indicating
1533 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001534static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535win32_wchdir(LPCWSTR path)
1536{
Victor Stinnered537822015-12-13 21:40:26 +01001537 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001538 int result;
1539 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001540
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 if(!SetCurrentDirectoryW(path))
1542 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001543 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 if (!result)
1545 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001546 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001547 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001548 if (!new_path) {
1549 SetLastError(ERROR_OUTOFMEMORY);
1550 return FALSE;
1551 }
1552 result = GetCurrentDirectoryW(result, new_path);
1553 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001554 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 return FALSE;
1556 }
1557 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001558 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1559 wcsncmp(new_path, L"//", 2) == 0);
1560 if (!is_unc_like_path) {
1561 env[1] = new_path[0];
1562 result = SetEnvironmentVariableW(env, new_path);
1563 }
Victor Stinnered537822015-12-13 21:40:26 +01001564 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001565 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001566 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001567}
1568#endif
1569
Martin v. Löwis14694662006-02-03 12:54:16 +00001570#ifdef MS_WINDOWS
1571/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1572 - time stamps are restricted to second resolution
1573 - file modification times suffer from forth-and-back conversions between
1574 UTC and local time
1575 Therefore, we implement our own stat, based on the Win32 API directly.
1576*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001577#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001578#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001579
Victor Stinner6036e442015-03-08 01:58:04 +01001580static void
Steve Dowercc16be82016-09-08 10:35:16 -07001581find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1582 BY_HANDLE_FILE_INFORMATION *info,
1583 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001584{
1585 memset(info, 0, sizeof(*info));
1586 info->dwFileAttributes = pFileData->dwFileAttributes;
1587 info->ftCreationTime = pFileData->ftCreationTime;
1588 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1589 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1590 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1591 info->nFileSizeLow = pFileData->nFileSizeLow;
1592/* info->nNumberOfLinks = 1; */
1593 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1594 *reparse_tag = pFileData->dwReserved0;
1595 else
1596 *reparse_tag = 0;
1597}
1598
Guido van Rossumd8faa362007-04-27 19:54:29 +00001599static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001600attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001601{
Victor Stinner8c62be82010-05-06 00:08:46 +00001602 HANDLE hFindFile;
1603 WIN32_FIND_DATAW FileData;
1604 hFindFile = FindFirstFileW(pszFile, &FileData);
1605 if (hFindFile == INVALID_HANDLE_VALUE)
1606 return FALSE;
1607 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001608 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001610}
1611
Brian Curtind25aef52011-06-13 15:16:04 -05001612static BOOL
1613get_target_path(HANDLE hdl, wchar_t **target_path)
1614{
1615 int buf_size, result_length;
1616 wchar_t *buf;
1617
1618 /* We have a good handle to the target, use it to determine
1619 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001620 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1621 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001622 if(!buf_size)
1623 return FALSE;
1624
Victor Stinnerc36674a2016-03-16 14:30:16 +01001625 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001626 if (!buf) {
1627 SetLastError(ERROR_OUTOFMEMORY);
1628 return FALSE;
1629 }
1630
Steve Dower2ea51c92015-03-20 21:49:12 -07001631 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001632 buf, buf_size, VOLUME_NAME_DOS);
1633
1634 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001635 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001636 return FALSE;
1637 }
1638
1639 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001640 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001641 return FALSE;
1642 }
1643
1644 buf[result_length] = 0;
1645
1646 *target_path = buf;
1647 return TRUE;
1648}
1649
1650static int
Steve Dowercc16be82016-09-08 10:35:16 -07001651win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001652 BOOL traverse)
1653{
Victor Stinner26de69d2011-06-17 15:15:38 +02001654 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001655 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001656 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001657 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001658 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001659 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660
Steve Dowercc16be82016-09-08 10:35:16 -07001661 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001663 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001664 0, /* share mode */
1665 NULL, /* security attributes */
1666 OPEN_EXISTING,
1667 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001668 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1669 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001670 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001671 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1672 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001673 NULL);
1674
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676 /* Either the target doesn't exist, or we don't have access to
1677 get a handle to it. If the former, we need to return an error.
1678 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001679 DWORD lastError = GetLastError();
1680 if (lastError != ERROR_ACCESS_DENIED &&
1681 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001682 return -1;
1683 /* Could not get attributes on open file. Fall back to
1684 reading the directory. */
1685 if (!attributes_from_dir(path, &info, &reparse_tag))
1686 /* Very strange. This should not fail now */
1687 return -1;
1688 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1689 if (traverse) {
1690 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001691 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001694 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001695 } else {
1696 if (!GetFileInformationByHandle(hFile, &info)) {
1697 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001698 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001699 }
1700 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001701 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1702 return -1;
1703
1704 /* Close the outer open file handle now that we're about to
1705 reopen it with different flags. */
1706 if (!CloseHandle(hFile))
1707 return -1;
1708
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001710 /* In order to call GetFinalPathNameByHandle we need to open
1711 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001712 hFile2 = CreateFileW(
1713 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1714 NULL, OPEN_EXISTING,
1715 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1716 NULL);
1717 if (hFile2 == INVALID_HANDLE_VALUE)
1718 return -1;
1719
1720 if (!get_target_path(hFile2, &target_path))
1721 return -1;
1722
Steve Dowercc16be82016-09-08 10:35:16 -07001723 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001724 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001725 return code;
1726 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001727 } else
1728 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001729 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001730 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001731
1732 /* Set S_IEXEC if it is an .exe, .bat, ... */
1733 dot = wcsrchr(path, '.');
1734 if (dot) {
1735 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1736 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1737 result->st_mode |= 0111;
1738 }
1739 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001740}
1741
1742static int
Steve Dowercc16be82016-09-08 10:35:16 -07001743win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001744{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001745 /* Protocol violation: we explicitly clear errno, instead of
1746 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001747 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001748 errno = 0;
1749 return code;
1750}
Brian Curtind25aef52011-06-13 15:16:04 -05001751/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001752
1753 In Posix, stat automatically traverses symlinks and returns the stat
1754 structure for the target. In Windows, the equivalent GetFileAttributes by
1755 default does not traverse symlinks and instead returns attributes for
1756 the symlink.
1757
1758 Therefore, win32_lstat will get the attributes traditionally, and
1759 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001760 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001761
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001762static int
Steve Dowercc16be82016-09-08 10:35:16 -07001763win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001764{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001766}
1767
Victor Stinner8c62be82010-05-06 00:08:46 +00001768static int
Steve Dowercc16be82016-09-08 10:35:16 -07001769win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001770{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001771 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001772}
1773
Martin v. Löwis14694662006-02-03 12:54:16 +00001774#endif /* MS_WINDOWS */
1775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001777"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001778This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001779 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1781\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001782Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1783or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001784\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001785See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786
1787static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"st_mode", "protection bits"},
1789 {"st_ino", "inode"},
1790 {"st_dev", "device"},
1791 {"st_nlink", "number of hard links"},
1792 {"st_uid", "user ID of owner"},
1793 {"st_gid", "group ID of owner"},
1794 {"st_size", "total size, in bytes"},
1795 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1796 {NULL, "integer time of last access"},
1797 {NULL, "integer time of last modification"},
1798 {NULL, "integer time of last change"},
1799 {"st_atime", "time of last access"},
1800 {"st_mtime", "time of last modification"},
1801 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001802 {"st_atime_ns", "time of last access in nanoseconds"},
1803 {"st_mtime_ns", "time of last modification in nanoseconds"},
1804 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001805#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001806 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001807#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001808#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001810#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001811#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001812 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001813#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001814#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001815 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001816#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001817#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001818 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001819#endif
1820#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001821 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001822#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001823#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1824 {"st_file_attributes", "Windows file attribute bits"},
1825#endif
jcea6c51d512018-01-28 14:00:08 +01001826#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1827 {"st_fstype", "Type of filesystem"},
1828#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001830};
1831
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001832#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001833#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001835#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001836#endif
1837
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001838#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001839#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1840#else
1841#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1842#endif
1843
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001844#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001845#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1846#else
1847#define ST_RDEV_IDX ST_BLOCKS_IDX
1848#endif
1849
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001850#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1851#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1852#else
1853#define ST_FLAGS_IDX ST_RDEV_IDX
1854#endif
1855
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001856#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001857#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001858#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001859#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001860#endif
1861
1862#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1863#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1864#else
1865#define ST_BIRTHTIME_IDX ST_GEN_IDX
1866#endif
1867
Zachary Ware63f277b2014-06-19 09:46:37 -05001868#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1869#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1870#else
1871#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1872#endif
1873
jcea6c51d512018-01-28 14:00:08 +01001874#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1875#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1876#else
1877#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1878#endif
1879
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001880static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 "stat_result", /* name */
1882 stat_result__doc__, /* doc */
1883 stat_result_fields,
1884 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001885};
1886
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001887PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001888"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1889This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001890 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001891or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001892\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001893See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001894
1895static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001896 {"f_bsize", },
1897 {"f_frsize", },
1898 {"f_blocks", },
1899 {"f_bfree", },
1900 {"f_bavail", },
1901 {"f_files", },
1902 {"f_ffree", },
1903 {"f_favail", },
1904 {"f_flag", },
1905 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001906 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001907 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001908};
1909
1910static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 "statvfs_result", /* name */
1912 statvfs_result__doc__, /* doc */
1913 statvfs_result_fields,
1914 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001915};
1916
Ross Lagerwall7807c352011-03-17 20:20:30 +02001917#if defined(HAVE_WAITID) && !defined(__APPLE__)
1918PyDoc_STRVAR(waitid_result__doc__,
1919"waitid_result: Result from waitid.\n\n\
1920This object may be accessed either as a tuple of\n\
1921 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1922or via the attributes si_pid, si_uid, and so on.\n\
1923\n\
1924See os.waitid for more information.");
1925
1926static PyStructSequence_Field waitid_result_fields[] = {
1927 {"si_pid", },
1928 {"si_uid", },
1929 {"si_signo", },
1930 {"si_status", },
1931 {"si_code", },
1932 {0}
1933};
1934
1935static PyStructSequence_Desc waitid_result_desc = {
1936 "waitid_result", /* name */
1937 waitid_result__doc__, /* doc */
1938 waitid_result_fields,
1939 5
1940};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001941static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02001942#endif
1943
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001944static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001945static PyTypeObject* StatResultType;
1946static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07001947#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001948static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001949#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001950static newfunc structseq_new;
1951
1952static PyObject *
1953statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1954{
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 PyStructSequence *result;
1956 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001957
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 result = (PyStructSequence*)structseq_new(type, args, kwds);
1959 if (!result)
1960 return NULL;
1961 /* If we have been initialized from a tuple,
1962 st_?time might be set to None. Initialize it
1963 from the int slots. */
1964 for (i = 7; i <= 9; i++) {
1965 if (result->ob_item[i+3] == Py_None) {
1966 Py_DECREF(Py_None);
1967 Py_INCREF(result->ob_item[i]);
1968 result->ob_item[i+3] = result->ob_item[i];
1969 }
1970 }
1971 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001972}
1973
1974
Larry Hastings6fe20b32012-04-19 15:07:49 -07001975static PyObject *billion = NULL;
1976
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001977static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001978fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001979{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001980 PyObject *s = _PyLong_FromTime_t(sec);
1981 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1982 PyObject *s_in_ns = NULL;
1983 PyObject *ns_total = NULL;
1984 PyObject *float_s = NULL;
1985
1986 if (!(s && ns_fractional))
1987 goto exit;
1988
1989 s_in_ns = PyNumber_Multiply(s, billion);
1990 if (!s_in_ns)
1991 goto exit;
1992
1993 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1994 if (!ns_total)
1995 goto exit;
1996
Victor Stinner01b5aab2017-10-24 02:02:00 -07001997 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1998 if (!float_s) {
1999 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002000 }
2001
2002 PyStructSequence_SET_ITEM(v, index, s);
2003 PyStructSequence_SET_ITEM(v, index+3, float_s);
2004 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2005 s = NULL;
2006 float_s = NULL;
2007 ns_total = NULL;
2008exit:
2009 Py_XDECREF(s);
2010 Py_XDECREF(ns_fractional);
2011 Py_XDECREF(s_in_ns);
2012 Py_XDECREF(ns_total);
2013 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002014}
2015
Tim Peters5aa91602002-01-30 05:46:57 +00002016/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002017 (used by posix_stat() and posix_fstat()) */
2018static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002019_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002020{
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002022 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002023 if (v == NULL)
2024 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002025
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002027 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002028 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002029#ifdef MS_WINDOWS
2030 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002031#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002032 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002033#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002035#if defined(MS_WINDOWS)
2036 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2037 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2038#else
2039 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2040 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2041#endif
xdegaye50e86032017-05-22 11:15:08 +02002042 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2043 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002044
Martin v. Löwis14694662006-02-03 12:54:16 +00002045#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 ansec = st->st_atim.tv_nsec;
2047 mnsec = st->st_mtim.tv_nsec;
2048 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002049#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 ansec = st->st_atimespec.tv_nsec;
2051 mnsec = st->st_mtimespec.tv_nsec;
2052 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002053#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 ansec = st->st_atime_nsec;
2055 mnsec = st->st_mtime_nsec;
2056 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002057#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002059#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002060 fill_time(v, 7, st->st_atime, ansec);
2061 fill_time(v, 8, st->st_mtime, mnsec);
2062 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002063
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002064#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2066 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002067#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002068#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2070 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002071#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002072#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2074 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002075#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2078 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002079#endif
2080#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002081 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002082 PyObject *val;
2083 unsigned long bsec,bnsec;
2084 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002085#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002086 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002087#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002088 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002089#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002090 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002091 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2092 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002093 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002094#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002095#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2097 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002098#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002099#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2100 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2101 PyLong_FromUnsignedLong(st->st_file_attributes));
2102#endif
jcea6c51d512018-01-28 14:00:08 +01002103#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2104 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2105 PyUnicode_FromString(st->st_fstype));
2106#endif
Fred Drake699f3522000-06-29 21:12:41 +00002107
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 if (PyErr_Occurred()) {
2109 Py_DECREF(v);
2110 return NULL;
2111 }
Fred Drake699f3522000-06-29 21:12:41 +00002112
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002114}
2115
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002116/* POSIX methods */
2117
Guido van Rossum94f6f721999-01-06 18:42:14 +00002118
2119static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002120posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002121 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002122{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002123 STRUCT_STAT st;
2124 int result;
2125
2126#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2127 if (follow_symlinks_specified(function_name, follow_symlinks))
2128 return NULL;
2129#endif
2130
2131 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2132 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2133 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2134 return NULL;
2135
2136 Py_BEGIN_ALLOW_THREADS
2137 if (path->fd != -1)
2138 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002139#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002140 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002141 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002142 else
Steve Dowercc16be82016-09-08 10:35:16 -07002143 result = win32_lstat(path->wide, &st);
2144#else
2145 else
2146#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002147 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2148 result = LSTAT(path->narrow, &st);
2149 else
Steve Dowercc16be82016-09-08 10:35:16 -07002150#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002151#ifdef HAVE_FSTATAT
2152 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2153 result = fstatat(dir_fd, path->narrow, &st,
2154 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2155 else
Steve Dowercc16be82016-09-08 10:35:16 -07002156#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002157 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002158#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002159 Py_END_ALLOW_THREADS
2160
Victor Stinner292c8352012-10-30 02:17:38 +01002161 if (result != 0) {
2162 return path_error(path);
2163 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002164
2165 return _pystat_fromstructstat(&st);
2166}
2167
Larry Hastings2f936352014-08-05 14:04:04 +10002168/*[python input]
2169
2170for s in """
2171
2172FACCESSAT
2173FCHMODAT
2174FCHOWNAT
2175FSTATAT
2176LINKAT
2177MKDIRAT
2178MKFIFOAT
2179MKNODAT
2180OPENAT
2181READLINKAT
2182SYMLINKAT
2183UNLINKAT
2184
2185""".strip().split():
2186 s = s.strip()
2187 print("""
2188#ifdef HAVE_{s}
2189 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002190#else
Larry Hastings2f936352014-08-05 14:04:04 +10002191 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002192#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002193""".rstrip().format(s=s))
2194
2195for s in """
2196
2197FCHDIR
2198FCHMOD
2199FCHOWN
2200FDOPENDIR
2201FEXECVE
2202FPATHCONF
2203FSTATVFS
2204FTRUNCATE
2205
2206""".strip().split():
2207 s = s.strip()
2208 print("""
2209#ifdef HAVE_{s}
2210 #define PATH_HAVE_{s} 1
2211#else
2212 #define PATH_HAVE_{s} 0
2213#endif
2214
2215""".rstrip().format(s=s))
2216[python start generated code]*/
2217
2218#ifdef HAVE_FACCESSAT
2219 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_FCHMODAT
2225 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_FCHOWNAT
2231 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_FSTATAT
2237 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_LINKAT
2243 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_MKDIRAT
2249 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_MKFIFOAT
2255 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_MKNODAT
2261 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_OPENAT
2267 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2268#else
2269 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2270#endif
2271
2272#ifdef HAVE_READLINKAT
2273 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2274#else
2275 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2276#endif
2277
2278#ifdef HAVE_SYMLINKAT
2279 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2280#else
2281 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2282#endif
2283
2284#ifdef HAVE_UNLINKAT
2285 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2286#else
2287 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2288#endif
2289
2290#ifdef HAVE_FCHDIR
2291 #define PATH_HAVE_FCHDIR 1
2292#else
2293 #define PATH_HAVE_FCHDIR 0
2294#endif
2295
2296#ifdef HAVE_FCHMOD
2297 #define PATH_HAVE_FCHMOD 1
2298#else
2299 #define PATH_HAVE_FCHMOD 0
2300#endif
2301
2302#ifdef HAVE_FCHOWN
2303 #define PATH_HAVE_FCHOWN 1
2304#else
2305 #define PATH_HAVE_FCHOWN 0
2306#endif
2307
2308#ifdef HAVE_FDOPENDIR
2309 #define PATH_HAVE_FDOPENDIR 1
2310#else
2311 #define PATH_HAVE_FDOPENDIR 0
2312#endif
2313
2314#ifdef HAVE_FEXECVE
2315 #define PATH_HAVE_FEXECVE 1
2316#else
2317 #define PATH_HAVE_FEXECVE 0
2318#endif
2319
2320#ifdef HAVE_FPATHCONF
2321 #define PATH_HAVE_FPATHCONF 1
2322#else
2323 #define PATH_HAVE_FPATHCONF 0
2324#endif
2325
2326#ifdef HAVE_FSTATVFS
2327 #define PATH_HAVE_FSTATVFS 1
2328#else
2329 #define PATH_HAVE_FSTATVFS 0
2330#endif
2331
2332#ifdef HAVE_FTRUNCATE
2333 #define PATH_HAVE_FTRUNCATE 1
2334#else
2335 #define PATH_HAVE_FTRUNCATE 0
2336#endif
2337/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002338
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002339#ifdef MS_WINDOWS
2340 #undef PATH_HAVE_FTRUNCATE
2341 #define PATH_HAVE_FTRUNCATE 1
2342#endif
Larry Hastings31826802013-10-19 00:09:25 -07002343
Larry Hastings61272b72014-01-07 12:41:53 -08002344/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002345
2346class path_t_converter(CConverter):
2347
2348 type = "path_t"
2349 impl_by_reference = True
2350 parse_by_reference = True
2351
2352 converter = 'path_converter'
2353
2354 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002355 # right now path_t doesn't support default values.
2356 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002357 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002358 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002359
Larry Hastings2f936352014-08-05 14:04:04 +10002360 if self.c_default not in (None, 'Py_None'):
2361 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002362
2363 self.nullable = nullable
2364 self.allow_fd = allow_fd
2365
Larry Hastings7726ac92014-01-31 22:03:12 -08002366 def pre_render(self):
2367 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002368 if isinstance(value, str):
2369 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002370 return str(int(bool(value)))
2371
2372 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002373 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002374 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002375 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002376 strify(self.nullable),
2377 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002378 )
2379
2380 def cleanup(self):
2381 return "path_cleanup(&" + self.name + ");\n"
2382
2383
2384class dir_fd_converter(CConverter):
2385 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002386
Larry Hastings2f936352014-08-05 14:04:04 +10002387 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002388 if self.default in (unspecified, None):
2389 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002390 if isinstance(requires, str):
2391 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2392 else:
2393 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002394
Larry Hastings2f936352014-08-05 14:04:04 +10002395class fildes_converter(CConverter):
2396 type = 'int'
2397 converter = 'fildes_converter'
2398
2399class uid_t_converter(CConverter):
2400 type = "uid_t"
2401 converter = '_Py_Uid_Converter'
2402
2403class gid_t_converter(CConverter):
2404 type = "gid_t"
2405 converter = '_Py_Gid_Converter'
2406
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002407class dev_t_converter(CConverter):
2408 type = 'dev_t'
2409 converter = '_Py_Dev_Converter'
2410
2411class dev_t_return_converter(unsigned_long_return_converter):
2412 type = 'dev_t'
2413 conversion_fn = '_PyLong_FromDev'
2414 unsigned_cast = '(dev_t)'
2415
Larry Hastings2f936352014-08-05 14:04:04 +10002416class FSConverter_converter(CConverter):
2417 type = 'PyObject *'
2418 converter = 'PyUnicode_FSConverter'
2419 def converter_init(self):
2420 if self.default is not unspecified:
2421 fail("FSConverter_converter does not support default values")
2422 self.c_default = 'NULL'
2423
2424 def cleanup(self):
2425 return "Py_XDECREF(" + self.name + ");\n"
2426
2427class pid_t_converter(CConverter):
2428 type = 'pid_t'
2429 format_unit = '" _Py_PARSE_PID "'
2430
2431class idtype_t_converter(int_converter):
2432 type = 'idtype_t'
2433
2434class id_t_converter(CConverter):
2435 type = 'id_t'
2436 format_unit = '" _Py_PARSE_PID "'
2437
Benjamin Petersonca470632016-09-06 13:47:26 -07002438class intptr_t_converter(CConverter):
2439 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002440 format_unit = '" _Py_PARSE_INTPTR "'
2441
2442class Py_off_t_converter(CConverter):
2443 type = 'Py_off_t'
2444 converter = 'Py_off_t_converter'
2445
2446class Py_off_t_return_converter(long_return_converter):
2447 type = 'Py_off_t'
2448 conversion_fn = 'PyLong_FromPy_off_t'
2449
2450class path_confname_converter(CConverter):
2451 type="int"
2452 converter="conv_path_confname"
2453
2454class confstr_confname_converter(path_confname_converter):
2455 converter='conv_confstr_confname'
2456
2457class sysconf_confname_converter(path_confname_converter):
2458 converter="conv_sysconf_confname"
2459
2460class sched_param_converter(CConverter):
2461 type = 'struct sched_param'
2462 converter = 'convert_sched_param'
2463 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002464
Larry Hastings61272b72014-01-07 12:41:53 -08002465[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002466/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002467
Larry Hastings61272b72014-01-07 12:41:53 -08002468/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002469
Larry Hastings2a727912014-01-16 11:32:01 -08002470os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002471
2472 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002473 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002474 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002475
2476 *
2477
Larry Hastings2f936352014-08-05 14:04:04 +10002478 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002479 If not None, it should be a file descriptor open to a directory,
2480 and path should be a relative string; path will then be relative to
2481 that directory.
2482
2483 follow_symlinks: bool = True
2484 If False, and the last element of the path is a symbolic link,
2485 stat will examine the symbolic link itself instead of the file
2486 the link points to.
2487
2488Perform a stat system call on the given path.
2489
2490dir_fd and follow_symlinks may not be implemented
2491 on your platform. If they are unavailable, using them will raise a
2492 NotImplementedError.
2493
2494It's an error to use dir_fd or follow_symlinks when specifying path as
2495 an open file descriptor.
2496
Larry Hastings61272b72014-01-07 12:41:53 -08002497[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002498
Larry Hastings31826802013-10-19 00:09:25 -07002499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002500os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002501/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002502{
2503 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2504}
2505
Larry Hastings2f936352014-08-05 14:04:04 +10002506
2507/*[clinic input]
2508os.lstat
2509
2510 path : path_t
2511
2512 *
2513
2514 dir_fd : dir_fd(requires='fstatat') = None
2515
2516Perform a stat system call on the given path, without following symbolic links.
2517
2518Like stat(), but do not follow symbolic links.
2519Equivalent to stat(path, follow_symlinks=False).
2520[clinic start generated code]*/
2521
Larry Hastings2f936352014-08-05 14:04:04 +10002522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002523os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2524/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002525{
2526 int follow_symlinks = 0;
2527 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2528}
Larry Hastings31826802013-10-19 00:09:25 -07002529
Larry Hastings2f936352014-08-05 14:04:04 +10002530
Larry Hastings61272b72014-01-07 12:41:53 -08002531/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002532os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002533
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002534 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002535 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002536
2537 mode: int
2538 Operating-system mode bitfield. Can be F_OK to test existence,
2539 or the inclusive-OR of R_OK, W_OK, and X_OK.
2540
2541 *
2542
Larry Hastings2f936352014-08-05 14:04:04 +10002543 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002544 If not None, it should be a file descriptor open to a directory,
2545 and path should be relative; path will then be relative to that
2546 directory.
2547
2548 effective_ids: bool = False
2549 If True, access will use the effective uid/gid instead of
2550 the real uid/gid.
2551
2552 follow_symlinks: bool = True
2553 If False, and the last element of the path is a symbolic link,
2554 access will examine the symbolic link itself instead of the file
2555 the link points to.
2556
2557Use the real uid/gid to test for access to a path.
2558
2559{parameters}
2560dir_fd, effective_ids, and follow_symlinks may not be implemented
2561 on your platform. If they are unavailable, using them will raise a
2562 NotImplementedError.
2563
2564Note that most operations will use the effective uid/gid, therefore this
2565 routine can be used in a suid/sgid environment to test if the invoking user
2566 has the specified access to the path.
2567
Larry Hastings61272b72014-01-07 12:41:53 -08002568[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002569
Larry Hastings2f936352014-08-05 14:04:04 +10002570static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002571os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002572 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002573/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002574{
Larry Hastings2f936352014-08-05 14:04:04 +10002575 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002576
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002577#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002578 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002579#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002580 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002581#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583#ifndef HAVE_FACCESSAT
2584 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002585 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002586
2587 if (effective_ids) {
2588 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002589 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002590 }
2591#endif
2592
2593#ifdef MS_WINDOWS
2594 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002595 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596 Py_END_ALLOW_THREADS
2597
2598 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002599 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002600 * * we didn't get a -1, and
2601 * * write access wasn't requested,
2602 * * or the file isn't read-only,
2603 * * or it's a directory.
2604 * (Directories cannot be read-only on Windows.)
2605 */
Larry Hastings2f936352014-08-05 14:04:04 +10002606 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002607 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002608 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002609 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610#else
2611
2612 Py_BEGIN_ALLOW_THREADS
2613#ifdef HAVE_FACCESSAT
2614 if ((dir_fd != DEFAULT_DIR_FD) ||
2615 effective_ids ||
2616 !follow_symlinks) {
2617 int flags = 0;
2618 if (!follow_symlinks)
2619 flags |= AT_SYMLINK_NOFOLLOW;
2620 if (effective_ids)
2621 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002622 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 }
2624 else
2625#endif
Larry Hastings31826802013-10-19 00:09:25 -07002626 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002628 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002629#endif
2630
Larry Hastings9cf065c2012-06-22 16:30:09 -07002631 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002632}
2633
Guido van Rossumd371ff11999-01-25 16:12:23 +00002634#ifndef F_OK
2635#define F_OK 0
2636#endif
2637#ifndef R_OK
2638#define R_OK 4
2639#endif
2640#ifndef W_OK
2641#define W_OK 2
2642#endif
2643#ifndef X_OK
2644#define X_OK 1
2645#endif
2646
Larry Hastings31826802013-10-19 00:09:25 -07002647
Guido van Rossumd371ff11999-01-25 16:12:23 +00002648#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002649/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002650os.ttyname -> DecodeFSDefault
2651
2652 fd: int
2653 Integer file descriptor handle.
2654
2655 /
2656
2657Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002658[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002659
Larry Hastings31826802013-10-19 00:09:25 -07002660static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002661os_ttyname_impl(PyObject *module, int fd)
2662/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002663{
2664 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665
Larry Hastings31826802013-10-19 00:09:25 -07002666 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002667 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002668 posix_error();
2669 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002670}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002671#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002672
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002674/*[clinic input]
2675os.ctermid
2676
2677Return the name of the controlling terminal for this process.
2678[clinic start generated code]*/
2679
Larry Hastings2f936352014-08-05 14:04:04 +10002680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002681os_ctermid_impl(PyObject *module)
2682/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002683{
Victor Stinner8c62be82010-05-06 00:08:46 +00002684 char *ret;
2685 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002686
Greg Wardb48bc172000-03-01 21:51:56 +00002687#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002688 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002689#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002690 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002691#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002692 if (ret == NULL)
2693 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002694 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002695}
Larry Hastings2f936352014-08-05 14:04:04 +10002696#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002697
Larry Hastings2f936352014-08-05 14:04:04 +10002698
2699/*[clinic input]
2700os.chdir
2701
2702 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2703
2704Change the current working directory to the specified path.
2705
2706path may always be specified as a string.
2707On some platforms, path may also be specified as an open file descriptor.
2708 If this functionality is unavailable, using it raises an exception.
2709[clinic start generated code]*/
2710
Larry Hastings2f936352014-08-05 14:04:04 +10002711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002712os_chdir_impl(PyObject *module, path_t *path)
2713/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002714{
2715 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716
2717 Py_BEGIN_ALLOW_THREADS
2718#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002719 /* on unix, success = 0, on windows, success = !0 */
2720 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721#else
2722#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002723 if (path->fd != -1)
2724 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002725 else
2726#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002727 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002728#endif
2729 Py_END_ALLOW_THREADS
2730
2731 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002732 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733 }
2734
Larry Hastings2f936352014-08-05 14:04:04 +10002735 Py_RETURN_NONE;
2736}
2737
2738
2739#ifdef HAVE_FCHDIR
2740/*[clinic input]
2741os.fchdir
2742
2743 fd: fildes
2744
2745Change to the directory of the given file descriptor.
2746
2747fd must be opened on a directory, not a file.
2748Equivalent to os.chdir(fd).
2749
2750[clinic start generated code]*/
2751
Fred Drake4d1e64b2002-04-15 19:40:07 +00002752static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002753os_fchdir_impl(PyObject *module, int fd)
2754/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002755{
Larry Hastings2f936352014-08-05 14:04:04 +10002756 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002757}
2758#endif /* HAVE_FCHDIR */
2759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002760
Larry Hastings2f936352014-08-05 14:04:04 +10002761/*[clinic input]
2762os.chmod
2763
2764 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002765 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002766 On some platforms, path may also be specified as an open file descriptor.
2767 If this functionality is unavailable, using it raises an exception.
2768
2769 mode: int
2770 Operating-system mode bitfield.
2771
2772 *
2773
2774 dir_fd : dir_fd(requires='fchmodat') = None
2775 If not None, it should be a file descriptor open to a directory,
2776 and path should be relative; path will then be relative to that
2777 directory.
2778
2779 follow_symlinks: bool = True
2780 If False, and the last element of the path is a symbolic link,
2781 chmod will modify the symbolic link itself instead of the file
2782 the link points to.
2783
2784Change the access permissions of a file.
2785
2786It is an error to use dir_fd or follow_symlinks when specifying path as
2787 an open file descriptor.
2788dir_fd and follow_symlinks may not be implemented on your platform.
2789 If they are unavailable, using them will raise a NotImplementedError.
2790
2791[clinic start generated code]*/
2792
Larry Hastings2f936352014-08-05 14:04:04 +10002793static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002794os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002795 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002796/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002797{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002800#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002803
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804#ifdef HAVE_FCHMODAT
2805 int fchmodat_nofollow_unsupported = 0;
2806#endif
2807
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2809 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002810 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811#endif
2812
2813#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002814 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002815 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002816 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 result = 0;
2818 else {
2819 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 attr &= ~FILE_ATTRIBUTE_READONLY;
2821 else
2822 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002823 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 }
2825 Py_END_ALLOW_THREADS
2826
2827 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002828 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 }
2830#else /* MS_WINDOWS */
2831 Py_BEGIN_ALLOW_THREADS
2832#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002833 if (path->fd != -1)
2834 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 else
2836#endif
2837#ifdef HAVE_LCHMOD
2838 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002839 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840 else
2841#endif
2842#ifdef HAVE_FCHMODAT
2843 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2844 /*
2845 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2846 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002847 * and then says it isn't implemented yet.
2848 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002849 *
2850 * Once it is supported, os.chmod will automatically
2851 * support dir_fd and follow_symlinks=False. (Hopefully.)
2852 * Until then, we need to be careful what exception we raise.
2853 */
Larry Hastings2f936352014-08-05 14:04:04 +10002854 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2856 /*
2857 * But wait! We can't throw the exception without allowing threads,
2858 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2859 */
2860 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002861 result &&
2862 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2863 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002864 }
2865 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002866#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002867 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002868 Py_END_ALLOW_THREADS
2869
2870 if (result) {
2871#ifdef HAVE_FCHMODAT
2872 if (fchmodat_nofollow_unsupported) {
2873 if (dir_fd != DEFAULT_DIR_FD)
2874 dir_fd_and_follow_symlinks_invalid("chmod",
2875 dir_fd, follow_symlinks);
2876 else
2877 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002878 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879 }
2880 else
2881#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002882 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002883 }
2884#endif
2885
Larry Hastings2f936352014-08-05 14:04:04 +10002886 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002887}
2888
Larry Hastings9cf065c2012-06-22 16:30:09 -07002889
Christian Heimes4e30a842007-11-30 22:12:06 +00002890#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002891/*[clinic input]
2892os.fchmod
2893
2894 fd: int
2895 mode: int
2896
2897Change the access permissions of the file given by file descriptor fd.
2898
2899Equivalent to os.chmod(fd, mode).
2900[clinic start generated code]*/
2901
Larry Hastings2f936352014-08-05 14:04:04 +10002902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002903os_fchmod_impl(PyObject *module, int fd, int mode)
2904/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002905{
2906 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002907 int async_err = 0;
2908
2909 do {
2910 Py_BEGIN_ALLOW_THREADS
2911 res = fchmod(fd, mode);
2912 Py_END_ALLOW_THREADS
2913 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2914 if (res != 0)
2915 return (!async_err) ? posix_error() : NULL;
2916
Victor Stinner8c62be82010-05-06 00:08:46 +00002917 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002918}
2919#endif /* HAVE_FCHMOD */
2920
Larry Hastings2f936352014-08-05 14:04:04 +10002921
Christian Heimes4e30a842007-11-30 22:12:06 +00002922#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002923/*[clinic input]
2924os.lchmod
2925
2926 path: path_t
2927 mode: int
2928
2929Change the access permissions of a file, without following symbolic links.
2930
2931If path is a symlink, this affects the link itself rather than the target.
2932Equivalent to chmod(path, mode, follow_symlinks=False)."
2933[clinic start generated code]*/
2934
Larry Hastings2f936352014-08-05 14:04:04 +10002935static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002936os_lchmod_impl(PyObject *module, path_t *path, int mode)
2937/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002938{
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002940 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002941 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002943 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002944 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002945 return NULL;
2946 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002947 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002948}
2949#endif /* HAVE_LCHMOD */
2950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002951
Thomas Wouterscf297e42007-02-23 15:07:44 +00002952#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002953/*[clinic input]
2954os.chflags
2955
2956 path: path_t
2957 flags: unsigned_long(bitwise=True)
2958 follow_symlinks: bool=True
2959
2960Set file flags.
2961
2962If follow_symlinks is False, and the last element of the path is a symbolic
2963 link, chflags will change flags on the symbolic link itself instead of the
2964 file the link points to.
2965follow_symlinks may not be implemented on your platform. If it is
2966unavailable, using it will raise a NotImplementedError.
2967
2968[clinic start generated code]*/
2969
Larry Hastings2f936352014-08-05 14:04:04 +10002970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002971os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002972 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002973/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002974{
2975 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002976
2977#ifndef HAVE_LCHFLAGS
2978 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002979 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980#endif
2981
Victor Stinner8c62be82010-05-06 00:08:46 +00002982 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002983#ifdef HAVE_LCHFLAGS
2984 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002985 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986 else
2987#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002988 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002989 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002990
Larry Hastings2f936352014-08-05 14:04:04 +10002991 if (result)
2992 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002993
Larry Hastings2f936352014-08-05 14:04:04 +10002994 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002995}
2996#endif /* HAVE_CHFLAGS */
2997
Larry Hastings2f936352014-08-05 14:04:04 +10002998
Thomas Wouterscf297e42007-02-23 15:07:44 +00002999#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003000/*[clinic input]
3001os.lchflags
3002
3003 path: path_t
3004 flags: unsigned_long(bitwise=True)
3005
3006Set file flags.
3007
3008This function will not follow symbolic links.
3009Equivalent to chflags(path, flags, follow_symlinks=False).
3010[clinic start generated code]*/
3011
Larry Hastings2f936352014-08-05 14:04:04 +10003012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003013os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3014/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003015{
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003018 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003019 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003020 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003021 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003022 }
Victor Stinner292c8352012-10-30 02:17:38 +01003023 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003024}
3025#endif /* HAVE_LCHFLAGS */
3026
Larry Hastings2f936352014-08-05 14:04:04 +10003027
Martin v. Löwis244edc82001-10-04 22:44:26 +00003028#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003029/*[clinic input]
3030os.chroot
3031 path: path_t
3032
3033Change root directory to path.
3034
3035[clinic start generated code]*/
3036
Larry Hastings2f936352014-08-05 14:04:04 +10003037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003038os_chroot_impl(PyObject *module, path_t *path)
3039/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003040{
3041 int res;
3042 Py_BEGIN_ALLOW_THREADS
3043 res = chroot(path->narrow);
3044 Py_END_ALLOW_THREADS
3045 if (res < 0)
3046 return path_error(path);
3047 Py_RETURN_NONE;
3048}
3049#endif /* HAVE_CHROOT */
3050
Martin v. Löwis244edc82001-10-04 22:44:26 +00003051
Guido van Rossum21142a01999-01-08 21:05:37 +00003052#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003053/*[clinic input]
3054os.fsync
3055
3056 fd: fildes
3057
3058Force write of fd to disk.
3059[clinic start generated code]*/
3060
Larry Hastings2f936352014-08-05 14:04:04 +10003061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003062os_fsync_impl(PyObject *module, int fd)
3063/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003064{
3065 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003066}
3067#endif /* HAVE_FSYNC */
3068
Larry Hastings2f936352014-08-05 14:04:04 +10003069
Ross Lagerwall7807c352011-03-17 20:20:30 +02003070#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003071/*[clinic input]
3072os.sync
3073
3074Force write of everything to disk.
3075[clinic start generated code]*/
3076
Larry Hastings2f936352014-08-05 14:04:04 +10003077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003078os_sync_impl(PyObject *module)
3079/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003080{
3081 Py_BEGIN_ALLOW_THREADS
3082 sync();
3083 Py_END_ALLOW_THREADS
3084 Py_RETURN_NONE;
3085}
Larry Hastings2f936352014-08-05 14:04:04 +10003086#endif /* HAVE_SYNC */
3087
Ross Lagerwall7807c352011-03-17 20:20:30 +02003088
Guido van Rossum21142a01999-01-08 21:05:37 +00003089#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003090#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003091extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3092#endif
3093
Larry Hastings2f936352014-08-05 14:04:04 +10003094/*[clinic input]
3095os.fdatasync
3096
3097 fd: fildes
3098
3099Force write of fd to disk without forcing update of metadata.
3100[clinic start generated code]*/
3101
Larry Hastings2f936352014-08-05 14:04:04 +10003102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003103os_fdatasync_impl(PyObject *module, int fd)
3104/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003105{
3106 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003107}
3108#endif /* HAVE_FDATASYNC */
3109
3110
Fredrik Lundh10723342000-07-10 16:38:09 +00003111#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003112/*[clinic input]
3113os.chown
3114
3115 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003116 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003117
3118 uid: uid_t
3119
3120 gid: gid_t
3121
3122 *
3123
3124 dir_fd : dir_fd(requires='fchownat') = None
3125 If not None, it should be a file descriptor open to a directory,
3126 and path should be relative; path will then be relative to that
3127 directory.
3128
3129 follow_symlinks: bool = True
3130 If False, and the last element of the path is a symbolic link,
3131 stat will examine the symbolic link itself instead of the file
3132 the link points to.
3133
3134Change the owner and group id of path to the numeric uid and gid.\
3135
3136path may always be specified as a string.
3137On some platforms, path may also be specified as an open file descriptor.
3138 If this functionality is unavailable, using it raises an exception.
3139If dir_fd is 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 directory.
3141If follow_symlinks is False, and the last element of the path is a symbolic
3142 link, chown will modify the symbolic link itself instead of the file the
3143 link points to.
3144It is an error to use dir_fd or follow_symlinks when specifying path as
3145 an open file descriptor.
3146dir_fd and follow_symlinks may not be implemented on your platform.
3147 If they are unavailable, using them will raise a NotImplementedError.
3148
3149[clinic start generated code]*/
3150
Larry Hastings2f936352014-08-05 14:04:04 +10003151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003152os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003153 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003154/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003155{
3156 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157
3158#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3159 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003160 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003162 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3163 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3164 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003165
3166#ifdef __APPLE__
3167 /*
3168 * This is for Mac OS X 10.3, which doesn't have lchown.
3169 * (But we still have an lchown symbol because of weak-linking.)
3170 * It doesn't have fchownat either. So there's no possibility
3171 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003172 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003173 if ((!follow_symlinks) && (lchown == NULL)) {
3174 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003175 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003176 }
3177#endif
3178
Victor Stinner8c62be82010-05-06 00:08:46 +00003179 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003180#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003181 if (path->fd != -1)
3182 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003183 else
3184#endif
3185#ifdef HAVE_LCHOWN
3186 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003187 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003188 else
3189#endif
3190#ifdef HAVE_FCHOWNAT
3191 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003192 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003193 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3194 else
3195#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003196 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003198
Larry Hastings2f936352014-08-05 14:04:04 +10003199 if (result)
3200 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003201
Larry Hastings2f936352014-08-05 14:04:04 +10003202 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003203}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003204#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003205
Larry Hastings2f936352014-08-05 14:04:04 +10003206
Christian Heimes4e30a842007-11-30 22:12:06 +00003207#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003208/*[clinic input]
3209os.fchown
3210
3211 fd: int
3212 uid: uid_t
3213 gid: gid_t
3214
3215Change the owner and group id of the file specified by file descriptor.
3216
3217Equivalent to os.chown(fd, uid, gid).
3218
3219[clinic start generated code]*/
3220
Larry Hastings2f936352014-08-05 14:04:04 +10003221static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003222os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3223/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003224{
Victor Stinner8c62be82010-05-06 00:08:46 +00003225 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003226 int async_err = 0;
3227
3228 do {
3229 Py_BEGIN_ALLOW_THREADS
3230 res = fchown(fd, uid, gid);
3231 Py_END_ALLOW_THREADS
3232 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3233 if (res != 0)
3234 return (!async_err) ? posix_error() : NULL;
3235
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003237}
3238#endif /* HAVE_FCHOWN */
3239
Larry Hastings2f936352014-08-05 14:04:04 +10003240
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003241#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003242/*[clinic input]
3243os.lchown
3244
3245 path : path_t
3246 uid: uid_t
3247 gid: gid_t
3248
3249Change the owner and group id of path to the numeric uid and gid.
3250
3251This function will not follow symbolic links.
3252Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3253[clinic start generated code]*/
3254
Larry Hastings2f936352014-08-05 14:04:04 +10003255static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003256os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3257/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003258{
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003261 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003262 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003263 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003264 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003265 }
Larry Hastings2f936352014-08-05 14:04:04 +10003266 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003267}
3268#endif /* HAVE_LCHOWN */
3269
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003270
Barry Warsaw53699e91996-12-10 23:23:01 +00003271static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003272posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003273{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003274 char *buf, *tmpbuf;
3275 char *cwd;
3276 const size_t chunk = 1024;
3277 size_t buflen = 0;
3278 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003279
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003280#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003282 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003283 wchar_t *wbuf2 = wbuf;
3284 PyObject *resobj;
3285 DWORD len;
3286 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003287 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 /* If the buffer is large enough, len does not include the
3289 terminating \0. If the buffer is too small, len includes
3290 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003291 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003292 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 if (wbuf2)
3294 len = GetCurrentDirectoryW(len, wbuf2);
3295 }
3296 Py_END_ALLOW_THREADS
3297 if (!wbuf2) {
3298 PyErr_NoMemory();
3299 return NULL;
3300 }
3301 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003302 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003303 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003304 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 }
3306 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003307 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003308 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003309 return resobj;
3310 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003311
3312 if (win32_warn_bytes_api())
3313 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003314#endif
3315
Victor Stinner4403d7d2015-04-25 00:16:10 +02003316 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003317 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003318 do {
3319 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003320#ifdef MS_WINDOWS
3321 if (buflen > INT_MAX) {
3322 PyErr_NoMemory();
3323 break;
3324 }
3325#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003326 tmpbuf = PyMem_RawRealloc(buf, buflen);
3327 if (tmpbuf == NULL)
3328 break;
3329
3330 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003331#ifdef MS_WINDOWS
3332 cwd = getcwd(buf, (int)buflen);
3333#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003334 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003335#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003338
3339 if (cwd == NULL) {
3340 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003341 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003342 }
3343
Victor Stinner8c62be82010-05-06 00:08:46 +00003344 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003345 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3346 else
3347 obj = PyUnicode_DecodeFSDefault(buf);
3348 PyMem_RawFree(buf);
3349
3350 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003351}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003352
Larry Hastings2f936352014-08-05 14:04:04 +10003353
3354/*[clinic input]
3355os.getcwd
3356
3357Return a unicode string representing the current working directory.
3358[clinic start generated code]*/
3359
Larry Hastings2f936352014-08-05 14:04:04 +10003360static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003361os_getcwd_impl(PyObject *module)
3362/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003363{
3364 return posix_getcwd(0);
3365}
3366
Larry Hastings2f936352014-08-05 14:04:04 +10003367
3368/*[clinic input]
3369os.getcwdb
3370
3371Return a bytes 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_getcwdb_impl(PyObject *module)
3376/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003377{
3378 return posix_getcwd(1);
3379}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003380
Larry Hastings2f936352014-08-05 14:04:04 +10003381
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3383#define HAVE_LINK 1
3384#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003385
Guido van Rossumb6775db1994-08-01 11:34:53 +00003386#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003387/*[clinic input]
3388
3389os.link
3390
3391 src : path_t
3392 dst : path_t
3393 *
3394 src_dir_fd : dir_fd = None
3395 dst_dir_fd : dir_fd = None
3396 follow_symlinks: bool = True
3397
3398Create a hard link to a file.
3399
3400If either src_dir_fd or dst_dir_fd is not None, it should be a file
3401 descriptor open to a directory, and the respective path string (src or dst)
3402 should be relative; the path will then be relative to that directory.
3403If follow_symlinks is False, and the last element of src is a symbolic
3404 link, link will create a link to the symbolic link itself instead of the
3405 file the link points to.
3406src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3407 platform. If they are unavailable, using them will raise a
3408 NotImplementedError.
3409[clinic start generated code]*/
3410
Larry Hastings2f936352014-08-05 14:04:04 +10003411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003412os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003413 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003414/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003415{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003417 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003418#else
3419 int result;
3420#endif
3421
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422#ifndef HAVE_LINKAT
3423 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3424 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003425 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 }
3427#endif
3428
Steve Dowercc16be82016-09-08 10:35:16 -07003429#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003430 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431 PyErr_SetString(PyExc_NotImplementedError,
3432 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003433 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 }
Steve Dowercc16be82016-09-08 10:35:16 -07003435#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003436
Brian Curtin1b9df392010-11-24 20:24:31 +00003437#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003439 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003441
Larry Hastings2f936352014-08-05 14:04:04 +10003442 if (!result)
3443 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444#else
3445 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003446#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3448 (dst_dir_fd != DEFAULT_DIR_FD) ||
3449 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003450 result = linkat(src_dir_fd, src->narrow,
3451 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3453 else
Steve Dowercc16be82016-09-08 10:35:16 -07003454#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003455 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003457
Larry Hastings2f936352014-08-05 14:04:04 +10003458 if (result)
3459 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003460#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461
Larry Hastings2f936352014-08-05 14:04:04 +10003462 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003463}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464#endif
3465
Brian Curtin1b9df392010-11-24 20:24:31 +00003466
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003467#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003468static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003469_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003470{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 PyObject *v;
3472 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3473 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003474 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003476 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478
Steve Dowercc16be82016-09-08 10:35:16 -07003479 WIN32_FIND_DATAW wFileData;
3480 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003481
Steve Dowercc16be82016-09-08 10:35:16 -07003482 if (!path->wide) { /* Default arg: "." */
3483 po_wchars = L".";
3484 len = 1;
3485 } else {
3486 po_wchars = path->wide;
3487 len = wcslen(path->wide);
3488 }
3489 /* The +5 is so we can append "\\*.*\0" */
3490 wnamebuf = PyMem_New(wchar_t, len + 5);
3491 if (!wnamebuf) {
3492 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003494 }
Steve Dowercc16be82016-09-08 10:35:16 -07003495 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003497 wchar_t wch = wnamebuf[len-1];
3498 if (wch != SEP && wch != ALTSEP && wch != L':')
3499 wnamebuf[len++] = SEP;
3500 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 }
Steve Dowercc16be82016-09-08 10:35:16 -07003502 if ((list = PyList_New(0)) == NULL) {
3503 goto exit;
3504 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003505 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003506 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003507 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 if (hFindFile == INVALID_HANDLE_VALUE) {
3509 int error = GetLastError();
3510 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 goto exit;
3512 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003513 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 }
3516 do {
3517 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003518 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3519 wcscmp(wFileData.cFileName, L"..") != 0) {
3520 v = PyUnicode_FromWideChar(wFileData.cFileName,
3521 wcslen(wFileData.cFileName));
3522 if (path->narrow && v) {
3523 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3524 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_DECREF(list);
3527 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 break;
3529 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003531 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 Py_DECREF(list);
3533 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 break;
3535 }
3536 Py_DECREF(v);
3537 }
3538 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003539 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 Py_END_ALLOW_THREADS
3541 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3542 it got to the end of the directory. */
3543 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003545 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 }
3548 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003549
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550exit:
3551 if (hFindFile != INVALID_HANDLE_VALUE) {
3552 if (FindClose(hFindFile) == FALSE) {
3553 if (list != NULL) {
3554 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003555 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 }
3557 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003559 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003560
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003562} /* end of _listdir_windows_no_opendir */
3563
3564#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3565
3566static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003567_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003568{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003569 PyObject *v;
3570 DIR *dirp = NULL;
3571 struct dirent *ep;
3572 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003573#ifdef HAVE_FDOPENDIR
3574 int fd = -1;
3575#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003576
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003579 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003581 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003582 if (fd == -1)
3583 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584
Larry Hastingsfdaea062012-06-25 04:42:23 -07003585 return_str = 1;
3586
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 Py_BEGIN_ALLOW_THREADS
3588 dirp = fdopendir(fd);
3589 Py_END_ALLOW_THREADS
3590 }
3591 else
3592#endif
3593 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003594 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003595 if (path->narrow) {
3596 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003597 /* only return bytes if they specified a bytes-like object */
3598 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003599 }
3600 else {
3601 name = ".";
3602 return_str = 1;
3603 }
3604
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605 Py_BEGIN_ALLOW_THREADS
3606 dirp = opendir(name);
3607 Py_END_ALLOW_THREADS
3608 }
3609
3610 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003611 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003612#ifdef HAVE_FDOPENDIR
3613 if (fd != -1) {
3614 Py_BEGIN_ALLOW_THREADS
3615 close(fd);
3616 Py_END_ALLOW_THREADS
3617 }
3618#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619 goto exit;
3620 }
3621 if ((list = PyList_New(0)) == NULL) {
3622 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 }
3624 for (;;) {
3625 errno = 0;
3626 Py_BEGIN_ALLOW_THREADS
3627 ep = readdir(dirp);
3628 Py_END_ALLOW_THREADS
3629 if (ep == NULL) {
3630 if (errno == 0) {
3631 break;
3632 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003634 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003636 }
3637 }
3638 if (ep->d_name[0] == '.' &&
3639 (NAMLEN(ep) == 1 ||
3640 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3641 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003642 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003643 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3644 else
3645 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 break;
3649 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003650 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003652 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 break;
3654 }
3655 Py_DECREF(v);
3656 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003657
Larry Hastings9cf065c2012-06-22 16:30:09 -07003658exit:
3659 if (dirp != NULL) {
3660 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003661#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 if (fd > -1)
3663 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003664#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003665 closedir(dirp);
3666 Py_END_ALLOW_THREADS
3667 }
3668
Larry Hastings9cf065c2012-06-22 16:30:09 -07003669 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003670} /* end of _posix_listdir */
3671#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003672
Larry Hastings2f936352014-08-05 14:04:04 +10003673
3674/*[clinic input]
3675os.listdir
3676
3677 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3678
3679Return a list containing the names of the files in the directory.
3680
BNMetricsb9427072018-11-02 15:20:19 +00003681path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003682 the filenames returned will also be bytes; in all other circumstances
3683 the filenames returned will be str.
3684If path is None, uses the path='.'.
3685On some platforms, path may also be specified as an open file descriptor;\
3686 the file descriptor must refer to a directory.
3687 If this functionality is unavailable, using it raises NotImplementedError.
3688
3689The list is in arbitrary order. It does not include the special
3690entries '.' and '..' even if they are present in the directory.
3691
3692
3693[clinic start generated code]*/
3694
Larry Hastings2f936352014-08-05 14:04:04 +10003695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003696os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003697/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003698{
3699#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3700 return _listdir_windows_no_opendir(path, NULL);
3701#else
3702 return _posix_listdir(path, NULL);
3703#endif
3704}
3705
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003706#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003707/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003708/*[clinic input]
3709os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003710
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003711 path: path_t
3712 /
3713
3714[clinic start generated code]*/
3715
3716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003717os__getfullpathname_impl(PyObject *module, path_t *path)
3718/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003719{
Steve Dowercc16be82016-09-08 10:35:16 -07003720 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3721 wchar_t *wtemp;
3722 DWORD result;
3723 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003724
Steve Dowercc16be82016-09-08 10:35:16 -07003725 result = GetFullPathNameW(path->wide,
3726 Py_ARRAY_LENGTH(woutbuf),
3727 woutbuf, &wtemp);
3728 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3729 woutbufp = PyMem_New(wchar_t, result);
3730 if (!woutbufp)
3731 return PyErr_NoMemory();
3732 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003733 }
Steve Dowercc16be82016-09-08 10:35:16 -07003734 if (result) {
3735 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3736 if (path->narrow)
3737 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3738 } else
3739 v = win32_error_object("GetFullPathNameW", path->object);
3740 if (woutbufp != woutbuf)
3741 PyMem_Free(woutbufp);
3742 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003743}
Brian Curtind40e6f72010-07-08 21:39:08 +00003744
Brian Curtind25aef52011-06-13 15:16:04 -05003745
Larry Hastings2f936352014-08-05 14:04:04 +10003746/*[clinic input]
3747os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003748
Steve Dower23ad6d02018-02-22 10:39:10 -08003749 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003750 /
3751
3752A helper function for samepath on windows.
3753[clinic start generated code]*/
3754
Larry Hastings2f936352014-08-05 14:04:04 +10003755static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003756os__getfinalpathname_impl(PyObject *module, path_t *path)
3757/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003758{
3759 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003760 wchar_t buf[MAXPATHLEN], *target_path = buf;
3761 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003762 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003763 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003764
Steve Dower23ad6d02018-02-22 10:39:10 -08003765 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003766 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003767 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003768 0, /* desired access */
3769 0, /* share mode */
3770 NULL, /* security attributes */
3771 OPEN_EXISTING,
3772 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3773 FILE_FLAG_BACKUP_SEMANTICS,
3774 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003775 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003776
Steve Dower23ad6d02018-02-22 10:39:10 -08003777 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003778 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003779 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003780
3781 /* We have a good handle to the target, use it to determine the
3782 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003783 while (1) {
3784 Py_BEGIN_ALLOW_THREADS
3785 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3786 buf_size, VOLUME_NAME_DOS);
3787 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003788
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003789 if (!result_length) {
3790 result = win32_error_object("GetFinalPathNameByHandleW",
3791 path->object);
3792 goto cleanup;
3793 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003794
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003795 if (result_length < buf_size) {
3796 break;
3797 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003798
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003799 wchar_t *tmp;
3800 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3801 result_length * sizeof(*tmp));
3802 if (!tmp) {
3803 result = PyErr_NoMemory();
3804 goto cleanup;
3805 }
3806
3807 buf_size = result_length;
3808 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003809 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003810
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003811 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003812 if (path->narrow)
3813 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003814
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003815cleanup:
3816 if (target_path != buf) {
3817 PyMem_Free(target_path);
3818 }
3819 CloseHandle(hFile);
3820 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003821}
Brian Curtin62857742010-09-06 17:07:27 +00003822
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003823/*[clinic input]
3824os._isdir
3825
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003826 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003827 /
3828
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003829Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003830[clinic start generated code]*/
3831
Brian Curtin9c669cc2011-06-08 18:17:18 -05003832static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003833os__isdir(PyObject *module, PyObject *arg)
3834/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003835{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003836 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003837 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3838
3839 if (!path_converter(arg, &path)) {
3840 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3841 PyErr_Clear();
3842 Py_RETURN_FALSE;
3843 }
3844 return NULL;
3845 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003846
Steve Dowerb22a6772016-07-17 20:49:38 -07003847 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003848 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003849 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003850
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003851 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003852 if (attributes == INVALID_FILE_ATTRIBUTES)
3853 Py_RETURN_FALSE;
3854
Brian Curtin9c669cc2011-06-08 18:17:18 -05003855 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3856 Py_RETURN_TRUE;
3857 else
3858 Py_RETURN_FALSE;
3859}
Tim Golden6b528062013-08-01 12:44:00 +01003860
Tim Golden6b528062013-08-01 12:44:00 +01003861
Larry Hastings2f936352014-08-05 14:04:04 +10003862/*[clinic input]
3863os._getvolumepathname
3864
Steve Dower23ad6d02018-02-22 10:39:10 -08003865 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003866
3867A helper function for ismount on Win32.
3868[clinic start generated code]*/
3869
Larry Hastings2f936352014-08-05 14:04:04 +10003870static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003871os__getvolumepathname_impl(PyObject *module, path_t *path)
3872/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003873{
3874 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003875 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003876 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003877 BOOL ret;
3878
Tim Golden6b528062013-08-01 12:44:00 +01003879 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003880 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003881
Victor Stinner850a18e2017-10-24 16:53:32 -07003882 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003883 PyErr_SetString(PyExc_OverflowError, "path too long");
3884 return NULL;
3885 }
3886
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003887 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003888 if (mountpath == NULL)
3889 return PyErr_NoMemory();
3890
3891 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003892 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003893 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003894 Py_END_ALLOW_THREADS
3895
3896 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003897 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003898 goto exit;
3899 }
3900 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003901 if (path->narrow)
3902 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003903
3904exit:
3905 PyMem_Free(mountpath);
3906 return result;
3907}
Tim Golden6b528062013-08-01 12:44:00 +01003908
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003909#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003910
Larry Hastings2f936352014-08-05 14:04:04 +10003911
3912/*[clinic input]
3913os.mkdir
3914
3915 path : path_t
3916
3917 mode: int = 0o777
3918
3919 *
3920
3921 dir_fd : dir_fd(requires='mkdirat') = None
3922
3923# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3924
3925Create a directory.
3926
3927If dir_fd is not None, it should be a file descriptor open to a directory,
3928 and path should be relative; path will then be relative to that directory.
3929dir_fd may not be implemented on your platform.
3930 If it is unavailable, using it will raise a NotImplementedError.
3931
3932The mode argument is ignored on Windows.
3933[clinic start generated code]*/
3934
Larry Hastings2f936352014-08-05 14:04:04 +10003935static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003936os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3937/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003938{
3939 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003940
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003941#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003942 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003943 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003944 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003945
Larry Hastings2f936352014-08-05 14:04:04 +10003946 if (!result)
3947 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003948#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003949 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003950#if HAVE_MKDIRAT
3951 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003952 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003953 else
3954#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003955#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003956 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003957#else
Larry Hastings2f936352014-08-05 14:04:04 +10003958 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003959#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003960 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003961 if (result < 0)
3962 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003963#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003964 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003965}
3966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003967
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003968/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3969#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003970#include <sys/resource.h>
3971#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003972
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003973
3974#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003975/*[clinic input]
3976os.nice
3977
3978 increment: int
3979 /
3980
3981Add increment to the priority of process and return the new priority.
3982[clinic start generated code]*/
3983
Larry Hastings2f936352014-08-05 14:04:04 +10003984static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003985os_nice_impl(PyObject *module, int increment)
3986/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003987{
3988 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003989
Victor Stinner8c62be82010-05-06 00:08:46 +00003990 /* There are two flavours of 'nice': one that returns the new
3991 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003992 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003993 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003994
Victor Stinner8c62be82010-05-06 00:08:46 +00003995 If we are of the nice family that returns the new priority, we
3996 need to clear errno before the call, and check if errno is filled
3997 before calling posix_error() on a returnvalue of -1, because the
3998 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003999
Victor Stinner8c62be82010-05-06 00:08:46 +00004000 errno = 0;
4001 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004002#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004003 if (value == 0)
4004 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004005#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004006 if (value == -1 && errno != 0)
4007 /* either nice() or getpriority() returned an error */
4008 return posix_error();
4009 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004010}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004011#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004012
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004013
4014#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004015/*[clinic input]
4016os.getpriority
4017
4018 which: int
4019 who: int
4020
4021Return program scheduling priority.
4022[clinic start generated code]*/
4023
Larry Hastings2f936352014-08-05 14:04:04 +10004024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004025os_getpriority_impl(PyObject *module, int which, int who)
4026/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004027{
4028 int retval;
4029
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004030 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004031 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004032 if (errno != 0)
4033 return posix_error();
4034 return PyLong_FromLong((long)retval);
4035}
4036#endif /* HAVE_GETPRIORITY */
4037
4038
4039#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004040/*[clinic input]
4041os.setpriority
4042
4043 which: int
4044 who: int
4045 priority: int
4046
4047Set program scheduling priority.
4048[clinic start generated code]*/
4049
Larry Hastings2f936352014-08-05 14:04:04 +10004050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004051os_setpriority_impl(PyObject *module, int which, int who, int priority)
4052/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004053{
4054 int retval;
4055
4056 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004057 if (retval == -1)
4058 return posix_error();
4059 Py_RETURN_NONE;
4060}
4061#endif /* HAVE_SETPRIORITY */
4062
4063
Barry Warsaw53699e91996-12-10 23:23:01 +00004064static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004065internal_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 +00004066{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004067 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004068 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004069
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004070#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004071 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004072 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004073#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004075#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076
Larry Hastings9cf065c2012-06-22 16:30:09 -07004077 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4078 (dst_dir_fd != DEFAULT_DIR_FD);
4079#ifndef HAVE_RENAMEAT
4080 if (dir_fd_specified) {
4081 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004082 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083 }
4084#endif
4085
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086#ifdef MS_WINDOWS
4087 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004088 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089 Py_END_ALLOW_THREADS
4090
Larry Hastings2f936352014-08-05 14:04:04 +10004091 if (!result)
4092 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093
4094#else
Steve Dowercc16be82016-09-08 10:35:16 -07004095 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4096 PyErr_Format(PyExc_ValueError,
4097 "%s: src and dst must be the same type", function_name);
4098 return NULL;
4099 }
4100
Larry Hastings9cf065c2012-06-22 16:30:09 -07004101 Py_BEGIN_ALLOW_THREADS
4102#ifdef HAVE_RENAMEAT
4103 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004104 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004105 else
4106#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004107 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108 Py_END_ALLOW_THREADS
4109
Larry Hastings2f936352014-08-05 14:04:04 +10004110 if (result)
4111 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004112#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004113 Py_RETURN_NONE;
4114}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115
Larry Hastings2f936352014-08-05 14:04:04 +10004116
4117/*[clinic input]
4118os.rename
4119
4120 src : path_t
4121 dst : path_t
4122 *
4123 src_dir_fd : dir_fd = None
4124 dst_dir_fd : dir_fd = None
4125
4126Rename a file or directory.
4127
4128If either src_dir_fd or dst_dir_fd is not None, it should be a file
4129 descriptor open to a directory, and the respective path string (src or dst)
4130 should be relative; the path will then be relative to that directory.
4131src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4132 If they are unavailable, using them will raise a NotImplementedError.
4133[clinic start generated code]*/
4134
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004136os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004137 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004138/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004139{
Larry Hastings2f936352014-08-05 14:04:04 +10004140 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004141}
4142
Larry Hastings2f936352014-08-05 14:04:04 +10004143
4144/*[clinic input]
4145os.replace = os.rename
4146
4147Rename a file or directory, overwriting the destination.
4148
4149If either src_dir_fd or dst_dir_fd is not None, it should be a file
4150 descriptor open to a directory, and the respective path string (src or dst)
4151 should be relative; the path will then be relative to that directory.
4152src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4153 If they are unavailable, using them will raise a NotImplementedError."
4154[clinic start generated code]*/
4155
Larry Hastings2f936352014-08-05 14:04:04 +10004156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004157os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4158 int dst_dir_fd)
4159/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004160{
4161 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4162}
4163
4164
4165/*[clinic input]
4166os.rmdir
4167
4168 path: path_t
4169 *
4170 dir_fd: dir_fd(requires='unlinkat') = None
4171
4172Remove a directory.
4173
4174If dir_fd is not None, it should be a file descriptor open to a directory,
4175 and path should be relative; path will then be relative to that directory.
4176dir_fd may not be implemented on your platform.
4177 If it is unavailable, using it will raise a NotImplementedError.
4178[clinic start generated code]*/
4179
Larry Hastings2f936352014-08-05 14:04:04 +10004180static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004181os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4182/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004183{
4184 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004185
4186 Py_BEGIN_ALLOW_THREADS
4187#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004188 /* Windows, success=1, UNIX, success=0 */
4189 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004190#else
4191#ifdef HAVE_UNLINKAT
4192 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004193 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004194 else
4195#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004196 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004197#endif
4198 Py_END_ALLOW_THREADS
4199
Larry Hastings2f936352014-08-05 14:04:04 +10004200 if (result)
4201 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004202
Larry Hastings2f936352014-08-05 14:04:04 +10004203 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004204}
4205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004206
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004207#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004208#ifdef MS_WINDOWS
4209/*[clinic input]
4210os.system -> long
4211
4212 command: Py_UNICODE
4213
4214Execute the command in a subshell.
4215[clinic start generated code]*/
4216
Larry Hastings2f936352014-08-05 14:04:04 +10004217static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004218os_system_impl(PyObject *module, Py_UNICODE *command)
4219/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004220{
4221 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004222 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004223 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004224 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004225 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004226 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004227 return result;
4228}
4229#else /* MS_WINDOWS */
4230/*[clinic input]
4231os.system -> long
4232
4233 command: FSConverter
4234
4235Execute the command in a subshell.
4236[clinic start generated code]*/
4237
Larry Hastings2f936352014-08-05 14:04:04 +10004238static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004239os_system_impl(PyObject *module, PyObject *command)
4240/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004241{
4242 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004243 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004244 Py_BEGIN_ALLOW_THREADS
4245 result = system(bytes);
4246 Py_END_ALLOW_THREADS
4247 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004248}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004249#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004250#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004252
Larry Hastings2f936352014-08-05 14:04:04 +10004253/*[clinic input]
4254os.umask
4255
4256 mask: int
4257 /
4258
4259Set the current numeric umask and return the previous umask.
4260[clinic start generated code]*/
4261
Larry Hastings2f936352014-08-05 14:04:04 +10004262static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004263os_umask_impl(PyObject *module, int mask)
4264/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004265{
4266 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 if (i < 0)
4268 return posix_error();
4269 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004270}
4271
Brian Curtind40e6f72010-07-08 21:39:08 +00004272#ifdef MS_WINDOWS
4273
4274/* override the default DeleteFileW behavior so that directory
4275symlinks can be removed with this function, the same as with
4276Unix symlinks */
4277BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4278{
4279 WIN32_FILE_ATTRIBUTE_DATA info;
4280 WIN32_FIND_DATAW find_data;
4281 HANDLE find_data_handle;
4282 int is_directory = 0;
4283 int is_link = 0;
4284
4285 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4286 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004287
Brian Curtind40e6f72010-07-08 21:39:08 +00004288 /* Get WIN32_FIND_DATA structure for the path to determine if
4289 it is a symlink */
4290 if(is_directory &&
4291 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4292 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4293
4294 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004295 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4296 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4297 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4298 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004299 FindClose(find_data_handle);
4300 }
4301 }
4302 }
4303
4304 if (is_directory && is_link)
4305 return RemoveDirectoryW(lpFileName);
4306
4307 return DeleteFileW(lpFileName);
4308}
4309#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004311
Larry Hastings2f936352014-08-05 14:04:04 +10004312/*[clinic input]
4313os.unlink
4314
4315 path: path_t
4316 *
4317 dir_fd: dir_fd(requires='unlinkat')=None
4318
4319Remove a file (same as remove()).
4320
4321If dir_fd is not None, it should be a file descriptor open to a directory,
4322 and path should be relative; path will then be relative to that directory.
4323dir_fd may not be implemented on your platform.
4324 If it is unavailable, using it will raise a NotImplementedError.
4325
4326[clinic start generated code]*/
4327
Larry Hastings2f936352014-08-05 14:04:04 +10004328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004329os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4330/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004331{
4332 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004333
4334 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004335 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004337 /* Windows, success=1, UNIX, success=0 */
4338 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004339#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004340#ifdef HAVE_UNLINKAT
4341 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004342 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004343 else
4344#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004345 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004347 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004348 Py_END_ALLOW_THREADS
4349
Larry Hastings2f936352014-08-05 14:04:04 +10004350 if (result)
4351 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004352
Larry Hastings2f936352014-08-05 14:04:04 +10004353 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004354}
4355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004356
Larry Hastings2f936352014-08-05 14:04:04 +10004357/*[clinic input]
4358os.remove = os.unlink
4359
4360Remove a file (same as unlink()).
4361
4362If dir_fd is not None, it should be a file descriptor open to a directory,
4363 and path should be relative; path will then be relative to that directory.
4364dir_fd may not be implemented on your platform.
4365 If it is unavailable, using it will raise a NotImplementedError.
4366[clinic start generated code]*/
4367
Larry Hastings2f936352014-08-05 14:04:04 +10004368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004369os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4370/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004371{
4372 return os_unlink_impl(module, path, dir_fd);
4373}
4374
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004375
Larry Hastings605a62d2012-06-24 04:33:36 -07004376static PyStructSequence_Field uname_result_fields[] = {
4377 {"sysname", "operating system name"},
4378 {"nodename", "name of machine on network (implementation-defined)"},
4379 {"release", "operating system release"},
4380 {"version", "operating system version"},
4381 {"machine", "hardware identifier"},
4382 {NULL}
4383};
4384
4385PyDoc_STRVAR(uname_result__doc__,
4386"uname_result: Result from os.uname().\n\n\
4387This object may be accessed either as a tuple of\n\
4388 (sysname, nodename, release, version, machine),\n\
4389or via the attributes sysname, nodename, release, version, and machine.\n\
4390\n\
4391See os.uname for more information.");
4392
4393static PyStructSequence_Desc uname_result_desc = {
4394 "uname_result", /* name */
4395 uname_result__doc__, /* doc */
4396 uname_result_fields,
4397 5
4398};
4399
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004400static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004401
4402
4403#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004404/*[clinic input]
4405os.uname
4406
4407Return an object identifying the current operating system.
4408
4409The object behaves like a named tuple with the following fields:
4410 (sysname, nodename, release, version, machine)
4411
4412[clinic start generated code]*/
4413
Larry Hastings2f936352014-08-05 14:04:04 +10004414static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004415os_uname_impl(PyObject *module)
4416/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004417{
Victor Stinner8c62be82010-05-06 00:08:46 +00004418 struct utsname u;
4419 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004420 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004421
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 Py_BEGIN_ALLOW_THREADS
4423 res = uname(&u);
4424 Py_END_ALLOW_THREADS
4425 if (res < 0)
4426 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004427
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004428 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004429 if (value == NULL)
4430 return NULL;
4431
4432#define SET(i, field) \
4433 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004434 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004435 if (!o) { \
4436 Py_DECREF(value); \
4437 return NULL; \
4438 } \
4439 PyStructSequence_SET_ITEM(value, i, o); \
4440 } \
4441
4442 SET(0, u.sysname);
4443 SET(1, u.nodename);
4444 SET(2, u.release);
4445 SET(3, u.version);
4446 SET(4, u.machine);
4447
4448#undef SET
4449
4450 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004451}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004452#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004453
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004454
Larry Hastings9cf065c2012-06-22 16:30:09 -07004455
4456typedef struct {
4457 int now;
4458 time_t atime_s;
4459 long atime_ns;
4460 time_t mtime_s;
4461 long mtime_ns;
4462} utime_t;
4463
4464/*
Victor Stinner484df002014-10-09 13:52:31 +02004465 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004466 * they also intentionally leak the declaration of a pointer named "time"
4467 */
4468#define UTIME_TO_TIMESPEC \
4469 struct timespec ts[2]; \
4470 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004471 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004472 time = NULL; \
4473 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004474 ts[0].tv_sec = ut->atime_s; \
4475 ts[0].tv_nsec = ut->atime_ns; \
4476 ts[1].tv_sec = ut->mtime_s; \
4477 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004478 time = ts; \
4479 } \
4480
4481#define UTIME_TO_TIMEVAL \
4482 struct timeval tv[2]; \
4483 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004484 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004485 time = NULL; \
4486 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004487 tv[0].tv_sec = ut->atime_s; \
4488 tv[0].tv_usec = ut->atime_ns / 1000; \
4489 tv[1].tv_sec = ut->mtime_s; \
4490 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004491 time = tv; \
4492 } \
4493
4494#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004495 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004497 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004498 time = NULL; \
4499 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004500 u.actime = ut->atime_s; \
4501 u.modtime = ut->mtime_s; \
4502 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004503 }
4504
4505#define UTIME_TO_TIME_T \
4506 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004507 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004508 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004509 time = NULL; \
4510 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004511 timet[0] = ut->atime_s; \
4512 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004513 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514 } \
4515
4516
Victor Stinner528a9ab2015-09-03 21:30:26 +02004517#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518
4519static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004520utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004521{
4522#ifdef HAVE_UTIMENSAT
4523 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4524 UTIME_TO_TIMESPEC;
4525 return utimensat(dir_fd, path, time, flags);
4526#elif defined(HAVE_FUTIMESAT)
4527 UTIME_TO_TIMEVAL;
4528 /*
4529 * follow_symlinks will never be false here;
4530 * we only allow !follow_symlinks and dir_fd together
4531 * if we have utimensat()
4532 */
4533 assert(follow_symlinks);
4534 return futimesat(dir_fd, path, time);
4535#endif
4536}
4537
Larry Hastings2f936352014-08-05 14:04:04 +10004538 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4539#else
4540 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541#endif
4542
Victor Stinner528a9ab2015-09-03 21:30:26 +02004543#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544
4545static int
Victor Stinner484df002014-10-09 13:52:31 +02004546utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547{
4548#ifdef HAVE_FUTIMENS
4549 UTIME_TO_TIMESPEC;
4550 return futimens(fd, time);
4551#else
4552 UTIME_TO_TIMEVAL;
4553 return futimes(fd, time);
4554#endif
4555}
4556
Larry Hastings2f936352014-08-05 14:04:04 +10004557 #define PATH_UTIME_HAVE_FD 1
4558#else
4559 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560#endif
4561
Victor Stinner5ebae872015-09-22 01:29:33 +02004562#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4563# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4564#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565
Victor Stinner4552ced2015-09-21 22:37:15 +02004566#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567
4568static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004569utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570{
4571#ifdef HAVE_UTIMENSAT
4572 UTIME_TO_TIMESPEC;
4573 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4574#else
4575 UTIME_TO_TIMEVAL;
4576 return lutimes(path, time);
4577#endif
4578}
4579
4580#endif
4581
4582#ifndef MS_WINDOWS
4583
4584static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004585utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586{
4587#ifdef HAVE_UTIMENSAT
4588 UTIME_TO_TIMESPEC;
4589 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4590#elif defined(HAVE_UTIMES)
4591 UTIME_TO_TIMEVAL;
4592 return utimes(path, time);
4593#elif defined(HAVE_UTIME_H)
4594 UTIME_TO_UTIMBUF;
4595 return utime(path, time);
4596#else
4597 UTIME_TO_TIME_T;
4598 return utime(path, time);
4599#endif
4600}
4601
4602#endif
4603
Larry Hastings76ad59b2012-05-03 00:30:07 -07004604static int
4605split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4606{
4607 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004608 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004609 divmod = PyNumber_Divmod(py_long, billion);
4610 if (!divmod)
4611 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004612 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4613 PyErr_Format(PyExc_TypeError,
4614 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4615 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4616 goto exit;
4617 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004618 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4619 if ((*s == -1) && PyErr_Occurred())
4620 goto exit;
4621 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004622 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004623 goto exit;
4624
4625 result = 1;
4626exit:
4627 Py_XDECREF(divmod);
4628 return result;
4629}
4630
Larry Hastings2f936352014-08-05 14:04:04 +10004631
4632/*[clinic input]
4633os.utime
4634
4635 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4636 times: object = NULL
4637 *
4638 ns: object = NULL
4639 dir_fd: dir_fd(requires='futimensat') = None
4640 follow_symlinks: bool=True
4641
Martin Panter0ff89092015-09-09 01:56:53 +00004642# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004643
4644Set the access and modified time of path.
4645
4646path may always be specified as a string.
4647On some platforms, path may also be specified as an open file descriptor.
4648 If this functionality is unavailable, using it raises an exception.
4649
4650If times is not None, it must be a tuple (atime, mtime);
4651 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004652If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004653 atime_ns and mtime_ns should be expressed as integer nanoseconds
4654 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004655If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004656Specifying tuples for both times and ns is an error.
4657
4658If dir_fd is not None, it should be a file descriptor open to a directory,
4659 and path should be relative; path will then be relative to that directory.
4660If follow_symlinks is False, and the last element of the path is a symbolic
4661 link, utime will modify the symbolic link itself instead of the file the
4662 link points to.
4663It is an error to use dir_fd or follow_symlinks when specifying path
4664 as an open file descriptor.
4665dir_fd and follow_symlinks may not be available on your platform.
4666 If they are unavailable, using them will raise a NotImplementedError.
4667
4668[clinic start generated code]*/
4669
Larry Hastings2f936352014-08-05 14:04:04 +10004670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004671os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4672 int dir_fd, int follow_symlinks)
4673/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004674{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675#ifdef MS_WINDOWS
4676 HANDLE hFile;
4677 FILETIME atime, mtime;
4678#else
4679 int result;
4680#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681
Larry Hastings2f936352014-08-05 14:04:04 +10004682 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004683
Christian Heimesb3c87242013-08-01 00:08:16 +02004684 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004685
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 if (times && (times != Py_None) && ns) {
4687 PyErr_SetString(PyExc_ValueError,
4688 "utime: you may specify either 'times'"
4689 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004690 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004691 }
4692
4693 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004694 time_t a_sec, m_sec;
4695 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004696 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 PyErr_SetString(PyExc_TypeError,
4698 "utime: 'times' must be either"
4699 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004700 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004701 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004703 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004704 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004705 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004706 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004707 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004708 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004709 utime.atime_s = a_sec;
4710 utime.atime_ns = a_nsec;
4711 utime.mtime_s = m_sec;
4712 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004713 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004715 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 PyErr_SetString(PyExc_TypeError,
4717 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004718 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004719 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004721 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004723 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004724 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004725 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004726 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 }
4728 else {
4729 /* times and ns are both None/unspecified. use "now". */
4730 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731 }
4732
Victor Stinner4552ced2015-09-21 22:37:15 +02004733#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004735 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004737
Larry Hastings2f936352014-08-05 14:04:04 +10004738 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4739 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4740 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004741 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004742
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743#if !defined(HAVE_UTIMENSAT)
4744 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004745 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 "utime: cannot use dir_fd and follow_symlinks "
4747 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004748 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004749 }
4750#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004751
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004752#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004754 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4755 NULL, OPEN_EXISTING,
4756 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 Py_END_ALLOW_THREADS
4758 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004759 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004760 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004761 }
4762
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004764 GetSystemTimeAsFileTime(&mtime);
4765 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004766 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004767 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004768 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4769 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004770 }
4771 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4772 /* Avoid putting the file name into the error here,
4773 as that may confuse the user into believing that
4774 something is wrong with the file, when it also
4775 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004776 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004777 CloseHandle(hFile);
4778 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004780 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004781#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004783
Victor Stinner4552ced2015-09-21 22:37:15 +02004784#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004786 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004788#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789
Victor Stinner528a9ab2015-09-03 21:30:26 +02004790#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004792 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793 else
4794#endif
4795
Victor Stinner528a9ab2015-09-03 21:30:26 +02004796#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004797 if (path->fd != -1)
4798 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 else
4800#endif
4801
Larry Hastings2f936352014-08-05 14:04:04 +10004802 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803
4804 Py_END_ALLOW_THREADS
4805
4806 if (result < 0) {
4807 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004808 posix_error();
4809 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004811
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004812#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004814 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004815}
4816
Guido van Rossum3b066191991-06-04 19:40:25 +00004817/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004818
Larry Hastings2f936352014-08-05 14:04:04 +10004819
4820/*[clinic input]
4821os._exit
4822
4823 status: int
4824
4825Exit to the system with specified status, without normal exit processing.
4826[clinic start generated code]*/
4827
Larry Hastings2f936352014-08-05 14:04:04 +10004828static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004829os__exit_impl(PyObject *module, int status)
4830/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004831{
4832 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004833 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004834}
4835
Steve Dowercc16be82016-09-08 10:35:16 -07004836#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4837#define EXECV_CHAR wchar_t
4838#else
4839#define EXECV_CHAR char
4840#endif
4841
Martin v. Löwis114619e2002-10-07 06:44:21 +00004842#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4843static void
Steve Dowercc16be82016-09-08 10:35:16 -07004844free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004845{
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 Py_ssize_t i;
4847 for (i = 0; i < count; i++)
4848 PyMem_Free(array[i]);
4849 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004850}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004851
Berker Peksag81816462016-09-15 20:19:47 +03004852static int
4853fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004854{
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004856 PyObject *ub;
4857 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004858#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004859 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004860 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004861 *out = PyUnicode_AsWideCharString(ub, &size);
4862 if (*out)
4863 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004864#else
Berker Peksag81816462016-09-15 20:19:47 +03004865 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004867 size = PyBytes_GET_SIZE(ub);
4868 *out = PyMem_Malloc(size + 1);
4869 if (*out) {
4870 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4871 result = 1;
4872 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004873 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004874#endif
Berker Peksag81816462016-09-15 20:19:47 +03004875 Py_DECREF(ub);
4876 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004877}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004878#endif
4879
Ross Lagerwall7807c352011-03-17 20:20:30 +02004880#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004881static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004882parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4883{
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 Py_ssize_t i, pos, envc;
4885 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004886 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004887 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004888
Victor Stinner8c62be82010-05-06 00:08:46 +00004889 i = PyMapping_Size(env);
4890 if (i < 0)
4891 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004892 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004893 if (envlist == NULL) {
4894 PyErr_NoMemory();
4895 return NULL;
4896 }
4897 envc = 0;
4898 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004899 if (!keys)
4900 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004902 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 goto error;
4904 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4905 PyErr_Format(PyExc_TypeError,
4906 "env.keys() or env.values() is not a list");
4907 goto error;
4908 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004909
Victor Stinner8c62be82010-05-06 00:08:46 +00004910 for (pos = 0; pos < i; pos++) {
4911 key = PyList_GetItem(keys, pos);
4912 val = PyList_GetItem(vals, pos);
4913 if (!key || !val)
4914 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004915
Berker Peksag81816462016-09-15 20:19:47 +03004916#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4917 if (!PyUnicode_FSDecoder(key, &key2))
4918 goto error;
4919 if (!PyUnicode_FSDecoder(val, &val2)) {
4920 Py_DECREF(key2);
4921 goto error;
4922 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004923 /* Search from index 1 because on Windows starting '=' is allowed for
4924 defining hidden environment variables. */
4925 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4926 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4927 {
4928 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004929 Py_DECREF(key2);
4930 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004931 goto error;
4932 }
Berker Peksag81816462016-09-15 20:19:47 +03004933 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4934#else
4935 if (!PyUnicode_FSConverter(key, &key2))
4936 goto error;
4937 if (!PyUnicode_FSConverter(val, &val2)) {
4938 Py_DECREF(key2);
4939 goto error;
4940 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004941 if (PyBytes_GET_SIZE(key2) == 0 ||
4942 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4943 {
4944 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004945 Py_DECREF(key2);
4946 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004947 goto error;
4948 }
Berker Peksag81816462016-09-15 20:19:47 +03004949 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4950 PyBytes_AS_STRING(val2));
4951#endif
4952 Py_DECREF(key2);
4953 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004954 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004955 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004956
4957 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4958 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 goto error;
4960 }
Berker Peksag81816462016-09-15 20:19:47 +03004961
Steve Dowercc16be82016-09-08 10:35:16 -07004962 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004963 }
4964 Py_DECREF(vals);
4965 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004966
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 envlist[envc] = 0;
4968 *envc_ptr = envc;
4969 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004970
4971error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 Py_XDECREF(keys);
4973 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004974 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004976}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004977
Steve Dowercc16be82016-09-08 10:35:16 -07004978static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004979parse_arglist(PyObject* argv, Py_ssize_t *argc)
4980{
4981 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004982 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004983 if (argvlist == NULL) {
4984 PyErr_NoMemory();
4985 return NULL;
4986 }
4987 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004988 PyObject* item = PySequence_ITEM(argv, i);
4989 if (item == NULL)
4990 goto fail;
4991 if (!fsconvert_strdup(item, &argvlist[i])) {
4992 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004993 goto fail;
4994 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004995 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004996 }
4997 argvlist[*argc] = NULL;
4998 return argvlist;
4999fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005000 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001 free_string_array(argvlist, *argc);
5002 return NULL;
5003}
Steve Dowercc16be82016-09-08 10:35:16 -07005004
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005#endif
5006
Larry Hastings2f936352014-08-05 14:04:04 +10005007
Ross Lagerwall7807c352011-03-17 20:20:30 +02005008#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005009/*[clinic input]
5010os.execv
5011
Steve Dowercc16be82016-09-08 10:35:16 -07005012 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005013 Path of executable file.
5014 argv: object
5015 Tuple or list of strings.
5016 /
5017
5018Execute an executable path with arguments, replacing current process.
5019[clinic start generated code]*/
5020
Larry Hastings2f936352014-08-05 14:04:04 +10005021static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005022os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5023/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005024{
Steve Dowercc16be82016-09-08 10:35:16 -07005025 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005026 Py_ssize_t argc;
5027
5028 /* execv has two arguments: (path, argv), where
5029 argv is a list or tuple of strings. */
5030
Ross Lagerwall7807c352011-03-17 20:20:30 +02005031 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5032 PyErr_SetString(PyExc_TypeError,
5033 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005034 return NULL;
5035 }
5036 argc = PySequence_Size(argv);
5037 if (argc < 1) {
5038 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005039 return NULL;
5040 }
5041
5042 argvlist = parse_arglist(argv, &argc);
5043 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005044 return NULL;
5045 }
Steve Dowerbce26262016-11-19 19:17:26 -08005046 if (!argvlist[0][0]) {
5047 PyErr_SetString(PyExc_ValueError,
5048 "execv() arg 2 first element cannot be empty");
5049 free_string_array(argvlist, argc);
5050 return NULL;
5051 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005052
Steve Dowerbce26262016-11-19 19:17:26 -08005053 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005054#ifdef HAVE_WEXECV
5055 _wexecv(path->wide, argvlist);
5056#else
5057 execv(path->narrow, argvlist);
5058#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005059 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005060
5061 /* If we get here it's definitely an error */
5062
5063 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005064 return posix_error();
5065}
5066
Larry Hastings2f936352014-08-05 14:04:04 +10005067
5068/*[clinic input]
5069os.execve
5070
5071 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5072 Path of executable file.
5073 argv: object
5074 Tuple or list of strings.
5075 env: object
5076 Dictionary of strings mapping to strings.
5077
5078Execute an executable path with arguments, replacing current process.
5079[clinic start generated code]*/
5080
Larry Hastings2f936352014-08-05 14:04:04 +10005081static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005082os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5083/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005084{
Steve Dowercc16be82016-09-08 10:35:16 -07005085 EXECV_CHAR **argvlist = NULL;
5086 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005087 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005088
Victor Stinner8c62be82010-05-06 00:08:46 +00005089 /* execve has three arguments: (path, argv, env), where
5090 argv is a list or tuple of strings and env is a dictionary
5091 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005092
Ross Lagerwall7807c352011-03-17 20:20:30 +02005093 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005095 "execve: argv must be a tuple or list");
5096 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005098 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005099 if (argc < 1) {
5100 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5101 return NULL;
5102 }
5103
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 if (!PyMapping_Check(env)) {
5105 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005106 "execve: environment must be a mapping object");
5107 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005109
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005112 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 }
Steve Dowerbce26262016-11-19 19:17:26 -08005114 if (!argvlist[0][0]) {
5115 PyErr_SetString(PyExc_ValueError,
5116 "execve: argv first element cannot be empty");
5117 goto fail;
5118 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005119
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 envlist = parse_envlist(env, &envc);
5121 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005122 goto fail;
5123
Steve Dowerbce26262016-11-19 19:17:26 -08005124 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005125#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005126 if (path->fd > -1)
5127 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005128 else
5129#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005130#ifdef HAVE_WEXECV
5131 _wexecve(path->wide, argvlist, envlist);
5132#else
Larry Hastings2f936352014-08-05 14:04:04 +10005133 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005134#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005135 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005136
5137 /* If we get here it's definitely an error */
5138
Alexey Izbyshev83460312018-10-20 03:28:22 +03005139 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005140
Steve Dowercc16be82016-09-08 10:35:16 -07005141 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005143 if (argvlist)
5144 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005145 return NULL;
5146}
Steve Dowercc16be82016-09-08 10:35:16 -07005147
Larry Hastings9cf065c2012-06-22 16:30:09 -07005148#endif /* HAVE_EXECV */
5149
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005150#ifdef HAVE_POSIX_SPAWN
5151
5152enum posix_spawn_file_actions_identifier {
5153 POSIX_SPAWN_OPEN,
5154 POSIX_SPAWN_CLOSE,
5155 POSIX_SPAWN_DUP2
5156};
5157
William Orr81574b82018-10-01 22:19:56 -07005158#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005159static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005160convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005161#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005162
5163static int
5164parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask,
5165 PyObject *setsigdef, PyObject *scheduler,
5166 posix_spawnattr_t *attrp)
5167{
5168 long all_flags = 0;
5169
5170 errno = posix_spawnattr_init(attrp);
5171 if (errno) {
5172 posix_error();
5173 return -1;
5174 }
5175
5176 if (setpgroup) {
5177 pid_t pgid = PyLong_AsPid(setpgroup);
5178 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5179 goto fail;
5180 }
5181 errno = posix_spawnattr_setpgroup(attrp, pgid);
5182 if (errno) {
5183 posix_error();
5184 goto fail;
5185 }
5186 all_flags |= POSIX_SPAWN_SETPGROUP;
5187 }
5188
5189 if (resetids) {
5190 all_flags |= POSIX_SPAWN_RESETIDS;
5191 }
5192
5193 if (setsigmask) {
5194 sigset_t set;
5195 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5196 goto fail;
5197 }
5198 errno = posix_spawnattr_setsigmask(attrp, &set);
5199 if (errno) {
5200 posix_error();
5201 goto fail;
5202 }
5203 all_flags |= POSIX_SPAWN_SETSIGMASK;
5204 }
5205
5206 if (setsigdef) {
5207 sigset_t set;
5208 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5209 goto fail;
5210 }
5211 errno = posix_spawnattr_setsigdefault(attrp, &set);
5212 if (errno) {
5213 posix_error();
5214 goto fail;
5215 }
5216 all_flags |= POSIX_SPAWN_SETSIGDEF;
5217 }
5218
5219 if (scheduler) {
5220#ifdef POSIX_SPAWN_SETSCHEDULER
5221 PyObject *py_schedpolicy;
5222 struct sched_param schedparam;
5223
5224 if (!PyArg_ParseTuple(scheduler, "OO&"
5225 ";A scheduler tuple must have two elements",
5226 &py_schedpolicy, convert_sched_param, &schedparam)) {
5227 goto fail;
5228 }
5229 if (py_schedpolicy != Py_None) {
5230 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5231
5232 if (schedpolicy == -1 && PyErr_Occurred()) {
5233 goto fail;
5234 }
5235 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5236 if (errno) {
5237 posix_error();
5238 goto fail;
5239 }
5240 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5241 }
5242 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5243 if (errno) {
5244 posix_error();
5245 goto fail;
5246 }
5247 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5248#else
5249 PyErr_SetString(PyExc_NotImplementedError,
5250 "The scheduler option is not supported in this system.");
5251 goto fail;
5252#endif
5253 }
5254
5255 errno = posix_spawnattr_setflags(attrp, all_flags);
5256 if (errno) {
5257 posix_error();
5258 goto fail;
5259 }
5260
5261 return 0;
5262
5263fail:
5264 (void)posix_spawnattr_destroy(attrp);
5265 return -1;
5266}
5267
5268static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005269parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005270 posix_spawn_file_actions_t *file_actionsp,
5271 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005272{
5273 PyObject *seq;
5274 PyObject *file_action = NULL;
5275 PyObject *tag_obj;
5276
5277 seq = PySequence_Fast(file_actions,
5278 "file_actions must be a sequence or None");
5279 if (seq == NULL) {
5280 return -1;
5281 }
5282
5283 errno = posix_spawn_file_actions_init(file_actionsp);
5284 if (errno) {
5285 posix_error();
5286 Py_DECREF(seq);
5287 return -1;
5288 }
5289
5290 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5291 file_action = PySequence_Fast_GET_ITEM(seq, i);
5292 Py_INCREF(file_action);
5293 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5294 PyErr_SetString(PyExc_TypeError,
5295 "Each file_actions element must be a non-empty tuple");
5296 goto fail;
5297 }
5298 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5299 if (tag == -1 && PyErr_Occurred()) {
5300 goto fail;
5301 }
5302
5303 /* Populate the file_actions object */
5304 switch (tag) {
5305 case POSIX_SPAWN_OPEN: {
5306 int fd, oflag;
5307 PyObject *path;
5308 unsigned long mode;
5309 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5310 ";A open file_action tuple must have 5 elements",
5311 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5312 &oflag, &mode))
5313 {
5314 goto fail;
5315 }
Pablo Galindocb970732018-06-19 09:19:50 +01005316 if (PyList_Append(temp_buffer, path)) {
5317 Py_DECREF(path);
5318 goto fail;
5319 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005320 errno = posix_spawn_file_actions_addopen(file_actionsp,
5321 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005322 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005323 if (errno) {
5324 posix_error();
5325 goto fail;
5326 }
5327 break;
5328 }
5329 case POSIX_SPAWN_CLOSE: {
5330 int fd;
5331 if (!PyArg_ParseTuple(file_action, "Oi"
5332 ";A close file_action tuple must have 2 elements",
5333 &tag_obj, &fd))
5334 {
5335 goto fail;
5336 }
5337 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5338 if (errno) {
5339 posix_error();
5340 goto fail;
5341 }
5342 break;
5343 }
5344 case POSIX_SPAWN_DUP2: {
5345 int fd1, fd2;
5346 if (!PyArg_ParseTuple(file_action, "Oii"
5347 ";A dup2 file_action tuple must have 3 elements",
5348 &tag_obj, &fd1, &fd2))
5349 {
5350 goto fail;
5351 }
5352 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5353 fd1, fd2);
5354 if (errno) {
5355 posix_error();
5356 goto fail;
5357 }
5358 break;
5359 }
5360 default: {
5361 PyErr_SetString(PyExc_TypeError,
5362 "Unknown file_actions identifier");
5363 goto fail;
5364 }
5365 }
5366 Py_DECREF(file_action);
5367 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005368
Serhiy Storchakaef347532018-05-01 16:45:04 +03005369 Py_DECREF(seq);
5370 return 0;
5371
5372fail:
5373 Py_DECREF(seq);
5374 Py_DECREF(file_action);
5375 (void)posix_spawn_file_actions_destroy(file_actionsp);
5376 return -1;
5377}
5378
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005379/*[clinic input]
5380
5381os.posix_spawn
5382 path: path_t
5383 Path of executable file.
5384 argv: object
5385 Tuple or list of strings.
5386 env: object
5387 Dictionary of strings mapping to strings.
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005388 /
Pablo Galindo254a4662018-09-07 16:44:24 +01005389 *
Serhiy Storchakad700f972018-09-08 14:48:18 +03005390 file_actions: object(c_default='NULL') = ()
5391 A sequence of file action tuples.
Pablo Galindo254a4662018-09-07 16:44:24 +01005392 setpgroup: object = NULL
5393 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5394 resetids: bool(accept={int}) = False
5395 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
5396 setsigmask: object(c_default='NULL') = ()
5397 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5398 setsigdef: object(c_default='NULL') = ()
5399 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5400 scheduler: object = NULL
5401 A tuple with the scheduler policy (optional) and parameters.
Serhiy Storchakad700f972018-09-08 14:48:18 +03005402
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005403Execute the program specified by path in a new process.
5404[clinic start generated code]*/
5405
5406static PyObject *
5407os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
Pablo Galindo254a4662018-09-07 16:44:24 +01005408 PyObject *env, PyObject *file_actions,
5409 PyObject *setpgroup, int resetids, PyObject *setsigmask,
5410 PyObject *setsigdef, PyObject *scheduler)
Serhiy Storchakad700f972018-09-08 14:48:18 +03005411/*[clinic end generated code: output=45dfa4c515d09f2c input=2891c2f1d457e39b]*/
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005412{
5413 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
5425 /* posix_spawn has 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)) {
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005430 PyErr_SetString(PyExc_TypeError,
5431 "posix_spawn: argv must be a tuple or list");
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) {
5436 PyErr_SetString(PyExc_ValueError, "posix_spawn: argv must not be empty");
5437 return NULL;
5438 }
5439
5440 if (!PyMapping_Check(env)) {
5441 PyErr_SetString(PyExc_TypeError,
5442 "posix_spawn: environment must be a mapping object");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005443 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005444 }
5445
5446 argvlist = parse_arglist(argv, &argc);
5447 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005448 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005449 }
5450 if (!argvlist[0][0]) {
5451 PyErr_SetString(PyExc_ValueError,
5452 "posix_spawn: argv first element cannot be empty");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005453 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005454 }
5455
5456 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005457 if (envlist == NULL) {
5458 goto exit;
5459 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005460
Serhiy Storchakad700f972018-09-08 14:48:18 +03005461 if (file_actions != NULL) {
Pablo Galindocb970732018-06-19 09:19:50 +01005462 /* There is a bug in old versions of glibc that makes some of the
5463 * helper functions for manipulating file actions not copy the provided
5464 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5465 * copy the value of path for some old versions of glibc (<2.20).
5466 * The use of temp_buffer here is a workaround that keeps the
5467 * python objects that own the buffers alive until posix_spawn gets called.
5468 * Check https://bugs.python.org/issue33630 and
5469 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5470 temp_buffer = PyList_New(0);
5471 if (!temp_buffer) {
5472 goto exit;
5473 }
5474 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005475 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005476 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005477 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005478 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005479
Pablo Galindo254a4662018-09-07 16:44:24 +01005480 if (parse_posix_spawn_flags(setpgroup, resetids, setsigmask,
5481 setsigdef, scheduler, &attr)) {
5482 goto exit;
5483 }
5484 attrp = &attr;
5485
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005486 _Py_BEGIN_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005487 err_code = posix_spawn(&pid, path->narrow,
Pablo Galindo254a4662018-09-07 16:44:24 +01005488 file_actionsp, attrp, argvlist, envlist);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005489 _Py_END_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005490 if (err_code) {
5491 errno = err_code;
5492 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005493 goto exit;
5494 }
5495 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005496
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005497exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005498 if (file_actionsp) {
5499 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005500 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005501 if (attrp) {
5502 (void)posix_spawnattr_destroy(attrp);
5503 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005504 if (envlist) {
5505 free_string_array(envlist, envc);
5506 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005507 if (argvlist) {
5508 free_string_array(argvlist, argc);
5509 }
Pablo Galindocb970732018-06-19 09:19:50 +01005510 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005511 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005512}
5513#endif /* HAVE_POSIX_SPAWN */
5514
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005515
Steve Dowercc16be82016-09-08 10:35:16 -07005516#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005517/*[clinic input]
5518os.spawnv
5519
5520 mode: int
5521 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005522 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005523 Path of executable file.
5524 argv: object
5525 Tuple or list of strings.
5526 /
5527
5528Execute the program specified by path in a new process.
5529[clinic start generated code]*/
5530
Larry Hastings2f936352014-08-05 14:04:04 +10005531static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005532os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5533/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005534{
Steve Dowercc16be82016-09-08 10:35:16 -07005535 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005536 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005537 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005538 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005539 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005540
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 /* spawnv has three arguments: (mode, path, argv), where
5542 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005543
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 if (PyList_Check(argv)) {
5545 argc = PyList_Size(argv);
5546 getitem = PyList_GetItem;
5547 }
5548 else if (PyTuple_Check(argv)) {
5549 argc = PyTuple_Size(argv);
5550 getitem = PyTuple_GetItem;
5551 }
5552 else {
5553 PyErr_SetString(PyExc_TypeError,
5554 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 return NULL;
5556 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005557 if (argc == 0) {
5558 PyErr_SetString(PyExc_ValueError,
5559 "spawnv() arg 2 cannot be empty");
5560 return NULL;
5561 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005562
Steve Dowercc16be82016-09-08 10:35:16 -07005563 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005564 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005565 return PyErr_NoMemory();
5566 }
5567 for (i = 0; i < argc; i++) {
5568 if (!fsconvert_strdup((*getitem)(argv, i),
5569 &argvlist[i])) {
5570 free_string_array(argvlist, i);
5571 PyErr_SetString(
5572 PyExc_TypeError,
5573 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 return NULL;
5575 }
Steve Dower93ff8722016-11-19 19:03:54 -08005576 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005577 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005578 PyErr_SetString(
5579 PyExc_ValueError,
5580 "spawnv() arg 2 first element cannot be empty");
5581 return NULL;
5582 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005583 }
5584 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005585
Victor Stinner8c62be82010-05-06 00:08:46 +00005586 if (mode == _OLD_P_OVERLAY)
5587 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005588
Victor Stinner8c62be82010-05-06 00:08:46 +00005589 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005590 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005591#ifdef HAVE_WSPAWNV
5592 spawnval = _wspawnv(mode, path->wide, argvlist);
5593#else
5594 spawnval = _spawnv(mode, path->narrow, argvlist);
5595#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005596 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005598
Victor Stinner8c62be82010-05-06 00:08:46 +00005599 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005600
Victor Stinner8c62be82010-05-06 00:08:46 +00005601 if (spawnval == -1)
5602 return posix_error();
5603 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005604 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005605}
5606
Larry Hastings2f936352014-08-05 14:04:04 +10005607/*[clinic input]
5608os.spawnve
5609
5610 mode: int
5611 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005612 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005613 Path of executable file.
5614 argv: object
5615 Tuple or list of strings.
5616 env: object
5617 Dictionary of strings mapping to strings.
5618 /
5619
5620Execute the program specified by path in a new process.
5621[clinic start generated code]*/
5622
Larry Hastings2f936352014-08-05 14:04:04 +10005623static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005624os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005625 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005626/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005627{
Steve Dowercc16be82016-09-08 10:35:16 -07005628 EXECV_CHAR **argvlist;
5629 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005630 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005631 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005632 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005633 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005634 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005635
Victor Stinner8c62be82010-05-06 00:08:46 +00005636 /* spawnve has four arguments: (mode, path, argv, env), where
5637 argv is a list or tuple of strings and env is a dictionary
5638 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005639
Victor Stinner8c62be82010-05-06 00:08:46 +00005640 if (PyList_Check(argv)) {
5641 argc = PyList_Size(argv);
5642 getitem = PyList_GetItem;
5643 }
5644 else if (PyTuple_Check(argv)) {
5645 argc = PyTuple_Size(argv);
5646 getitem = PyTuple_GetItem;
5647 }
5648 else {
5649 PyErr_SetString(PyExc_TypeError,
5650 "spawnve() arg 2 must be a tuple or list");
5651 goto fail_0;
5652 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005653 if (argc == 0) {
5654 PyErr_SetString(PyExc_ValueError,
5655 "spawnve() arg 2 cannot be empty");
5656 goto fail_0;
5657 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005658 if (!PyMapping_Check(env)) {
5659 PyErr_SetString(PyExc_TypeError,
5660 "spawnve() arg 3 must be a mapping object");
5661 goto fail_0;
5662 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005663
Steve Dowercc16be82016-09-08 10:35:16 -07005664 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005665 if (argvlist == NULL) {
5666 PyErr_NoMemory();
5667 goto fail_0;
5668 }
5669 for (i = 0; i < argc; i++) {
5670 if (!fsconvert_strdup((*getitem)(argv, i),
5671 &argvlist[i]))
5672 {
5673 lastarg = i;
5674 goto fail_1;
5675 }
Steve Dowerbce26262016-11-19 19:17:26 -08005676 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005677 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005678 PyErr_SetString(
5679 PyExc_ValueError,
5680 "spawnv() arg 2 first element cannot be empty");
5681 goto fail_1;
5682 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 }
5684 lastarg = argc;
5685 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005686
Victor Stinner8c62be82010-05-06 00:08:46 +00005687 envlist = parse_envlist(env, &envc);
5688 if (envlist == NULL)
5689 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005690
Victor Stinner8c62be82010-05-06 00:08:46 +00005691 if (mode == _OLD_P_OVERLAY)
5692 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005693
Victor Stinner8c62be82010-05-06 00:08:46 +00005694 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005695 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005696#ifdef HAVE_WSPAWNV
5697 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5698#else
5699 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5700#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005701 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005702 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005703
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 if (spawnval == -1)
5705 (void) posix_error();
5706 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005707 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005708
Victor Stinner8c62be82010-05-06 00:08:46 +00005709 while (--envc >= 0)
5710 PyMem_DEL(envlist[envc]);
5711 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005712 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005713 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005714 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005715 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005716}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005717
Guido van Rossuma1065681999-01-25 23:20:23 +00005718#endif /* HAVE_SPAWNV */
5719
5720
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005721#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005722
5723/* Helper function to validate arguments.
5724 Returns 0 on success. non-zero on failure with a TypeError raised.
5725 If obj is non-NULL it must be callable. */
5726static int
5727check_null_or_callable(PyObject *obj, const char* obj_name)
5728{
5729 if (obj && !PyCallable_Check(obj)) {
5730 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5731 obj_name, Py_TYPE(obj)->tp_name);
5732 return -1;
5733 }
5734 return 0;
5735}
5736
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005737/*[clinic input]
5738os.register_at_fork
5739
Gregory P. Smith163468a2017-05-29 10:03:41 -07005740 *
5741 before: object=NULL
5742 A callable to be called in the parent before the fork() syscall.
5743 after_in_child: object=NULL
5744 A callable to be called in the child after fork().
5745 after_in_parent: object=NULL
5746 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005747
Gregory P. Smith163468a2017-05-29 10:03:41 -07005748Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005749
Gregory P. Smith163468a2017-05-29 10:03:41 -07005750'before' callbacks are called in reverse order.
5751'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005752
5753[clinic start generated code]*/
5754
5755static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005756os_register_at_fork_impl(PyObject *module, PyObject *before,
5757 PyObject *after_in_child, PyObject *after_in_parent)
5758/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005759{
5760 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005761
Gregory P. Smith163468a2017-05-29 10:03:41 -07005762 if (!before && !after_in_child && !after_in_parent) {
5763 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5764 return NULL;
5765 }
5766 if (check_null_or_callable(before, "before") ||
5767 check_null_or_callable(after_in_child, "after_in_child") ||
5768 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005769 return NULL;
5770 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005771 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005772
Gregory P. Smith163468a2017-05-29 10:03:41 -07005773 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005774 return NULL;
5775 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005776 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005777 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005778 }
5779 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5780 return NULL;
5781 }
5782 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005783}
5784#endif /* HAVE_FORK */
5785
5786
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005787#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005788/*[clinic input]
5789os.fork1
5790
5791Fork a child process with a single multiplexed (i.e., not bound) thread.
5792
5793Return 0 to child process and PID of child to parent process.
5794[clinic start generated code]*/
5795
Larry Hastings2f936352014-08-05 14:04:04 +10005796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005797os_fork1_impl(PyObject *module)
5798/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005799{
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005801
Eric Snow59032962018-09-14 14:17:20 -07005802 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5803 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5804 return NULL;
5805 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005806 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005807 pid = fork1();
5808 if (pid == 0) {
5809 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005810 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005811 } else {
5812 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005813 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 }
5815 if (pid == -1)
5816 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005818}
Larry Hastings2f936352014-08-05 14:04:04 +10005819#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005820
5821
Guido van Rossumad0ee831995-03-01 10:34:45 +00005822#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005823/*[clinic input]
5824os.fork
5825
5826Fork a child process.
5827
5828Return 0 to child process and PID of child to parent process.
5829[clinic start generated code]*/
5830
Larry Hastings2f936352014-08-05 14:04:04 +10005831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005832os_fork_impl(PyObject *module)
5833/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005834{
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005836
Eric Snow59032962018-09-14 14:17:20 -07005837 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5838 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5839 return NULL;
5840 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005841 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005842 pid = fork();
5843 if (pid == 0) {
5844 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005845 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005846 } else {
5847 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005848 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005849 }
5850 if (pid == -1)
5851 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005852 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005853}
Larry Hastings2f936352014-08-05 14:04:04 +10005854#endif /* HAVE_FORK */
5855
Guido van Rossum85e3b011991-06-03 12:42:10 +00005856
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005857#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005858#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005859/*[clinic input]
5860os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005861
Larry Hastings2f936352014-08-05 14:04:04 +10005862 policy: int
5863
5864Get the maximum scheduling priority for policy.
5865[clinic start generated code]*/
5866
Larry Hastings2f936352014-08-05 14:04:04 +10005867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005868os_sched_get_priority_max_impl(PyObject *module, int policy)
5869/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005870{
5871 int max;
5872
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005873 max = sched_get_priority_max(policy);
5874 if (max < 0)
5875 return posix_error();
5876 return PyLong_FromLong(max);
5877}
5878
Larry Hastings2f936352014-08-05 14:04:04 +10005879
5880/*[clinic input]
5881os.sched_get_priority_min
5882
5883 policy: int
5884
5885Get the minimum scheduling priority for policy.
5886[clinic start generated code]*/
5887
Larry Hastings2f936352014-08-05 14:04:04 +10005888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005889os_sched_get_priority_min_impl(PyObject *module, int policy)
5890/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005891{
5892 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005893 if (min < 0)
5894 return posix_error();
5895 return PyLong_FromLong(min);
5896}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005897#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5898
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005899
Larry Hastings2f936352014-08-05 14:04:04 +10005900#ifdef HAVE_SCHED_SETSCHEDULER
5901/*[clinic input]
5902os.sched_getscheduler
5903 pid: pid_t
5904 /
5905
5906Get the scheduling policy for the process identifiedy by pid.
5907
5908Passing 0 for pid returns the scheduling policy for the calling process.
5909[clinic start generated code]*/
5910
Larry Hastings2f936352014-08-05 14:04:04 +10005911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005912os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5913/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005914{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005915 int policy;
5916
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005917 policy = sched_getscheduler(pid);
5918 if (policy < 0)
5919 return posix_error();
5920 return PyLong_FromLong(policy);
5921}
Larry Hastings2f936352014-08-05 14:04:04 +10005922#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005923
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005924
William Orr81574b82018-10-01 22:19:56 -07005925#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005926/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005927class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10005928
5929@classmethod
5930os.sched_param.__new__
5931
5932 sched_priority: object
5933 A scheduling parameter.
5934
5935Current has only one field: sched_priority");
5936[clinic start generated code]*/
5937
Larry Hastings2f936352014-08-05 14:04:04 +10005938static PyObject *
5939os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005940/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005941{
5942 PyObject *res;
5943
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005944 res = PyStructSequence_New(type);
5945 if (!res)
5946 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005947 Py_INCREF(sched_priority);
5948 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005949 return res;
5950}
5951
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005952
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005953PyDoc_VAR(os_sched_param__doc__);
5954
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005955static PyStructSequence_Field sched_param_fields[] = {
5956 {"sched_priority", "the scheduling priority"},
5957 {0}
5958};
5959
5960static PyStructSequence_Desc sched_param_desc = {
5961 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005962 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005963 sched_param_fields,
5964 1
5965};
5966
5967static int
5968convert_sched_param(PyObject *param, struct sched_param *res)
5969{
5970 long priority;
5971
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005972 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005973 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5974 return 0;
5975 }
5976 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5977 if (priority == -1 && PyErr_Occurred())
5978 return 0;
5979 if (priority > INT_MAX || priority < INT_MIN) {
5980 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5981 return 0;
5982 }
5983 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5984 return 1;
5985}
William Orr81574b82018-10-01 22:19:56 -07005986#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005987
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005988
5989#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005990/*[clinic input]
5991os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005992
Larry Hastings2f936352014-08-05 14:04:04 +10005993 pid: pid_t
5994 policy: int
5995 param: sched_param
5996 /
5997
5998Set the scheduling policy for the process identified by pid.
5999
6000If pid is 0, the calling process is changed.
6001param is an instance of sched_param.
6002[clinic start generated code]*/
6003
Larry Hastings2f936352014-08-05 14:04:04 +10006004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006005os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006006 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006007/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006008{
Jesus Cea9c822272011-09-10 01:40:52 +02006009 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006010 ** sched_setscheduler() returns 0 in Linux, but the previous
6011 ** scheduling policy under Solaris/Illumos, and others.
6012 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006013 */
Larry Hastings2f936352014-08-05 14:04:04 +10006014 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006015 return posix_error();
6016 Py_RETURN_NONE;
6017}
Larry Hastings2f936352014-08-05 14:04:04 +10006018#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006019
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006020
6021#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006022/*[clinic input]
6023os.sched_getparam
6024 pid: pid_t
6025 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006026
Larry Hastings2f936352014-08-05 14:04:04 +10006027Returns scheduling parameters for the process identified by pid.
6028
6029If pid is 0, returns parameters for the calling process.
6030Return value is an instance of sched_param.
6031[clinic start generated code]*/
6032
Larry Hastings2f936352014-08-05 14:04:04 +10006033static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006034os_sched_getparam_impl(PyObject *module, pid_t pid)
6035/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006036{
6037 struct sched_param param;
6038 PyObject *result;
6039 PyObject *priority;
6040
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006041 if (sched_getparam(pid, &param))
6042 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006043 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006044 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006045 return NULL;
6046 priority = PyLong_FromLong(param.sched_priority);
6047 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006048 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006049 return NULL;
6050 }
Larry Hastings2f936352014-08-05 14:04:04 +10006051 PyStructSequence_SET_ITEM(result, 0, priority);
6052 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006053}
6054
Larry Hastings2f936352014-08-05 14:04:04 +10006055
6056/*[clinic input]
6057os.sched_setparam
6058 pid: pid_t
6059 param: sched_param
6060 /
6061
6062Set scheduling parameters for the process identified by pid.
6063
6064If pid is 0, sets parameters for the calling process.
6065param should be an instance of sched_param.
6066[clinic start generated code]*/
6067
Larry Hastings2f936352014-08-05 14:04:04 +10006068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006069os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006070 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006071/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006072{
6073 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006074 return posix_error();
6075 Py_RETURN_NONE;
6076}
Larry Hastings2f936352014-08-05 14:04:04 +10006077#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006078
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006079
6080#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006081/*[clinic input]
6082os.sched_rr_get_interval -> double
6083 pid: pid_t
6084 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006085
Larry Hastings2f936352014-08-05 14:04:04 +10006086Return the round-robin quantum for the process identified by pid, in seconds.
6087
6088Value returned is a float.
6089[clinic start generated code]*/
6090
Larry Hastings2f936352014-08-05 14:04:04 +10006091static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006092os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6093/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006094{
6095 struct timespec interval;
6096 if (sched_rr_get_interval(pid, &interval)) {
6097 posix_error();
6098 return -1.0;
6099 }
6100 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6101}
6102#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006103
Larry Hastings2f936352014-08-05 14:04:04 +10006104
6105/*[clinic input]
6106os.sched_yield
6107
6108Voluntarily relinquish the CPU.
6109[clinic start generated code]*/
6110
Larry Hastings2f936352014-08-05 14:04:04 +10006111static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006112os_sched_yield_impl(PyObject *module)
6113/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006114{
6115 if (sched_yield())
6116 return posix_error();
6117 Py_RETURN_NONE;
6118}
6119
Benjamin Peterson2740af82011-08-02 17:41:34 -05006120#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006121/* The minimum number of CPUs allocated in a cpu_set_t */
6122static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006123
Larry Hastings2f936352014-08-05 14:04:04 +10006124/*[clinic input]
6125os.sched_setaffinity
6126 pid: pid_t
6127 mask : object
6128 /
6129
6130Set the CPU affinity of the process identified by pid to mask.
6131
6132mask should be an iterable of integers identifying CPUs.
6133[clinic start generated code]*/
6134
Larry Hastings2f936352014-08-05 14:04:04 +10006135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006136os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6137/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006138{
Antoine Pitrou84869872012-08-04 16:16:35 +02006139 int ncpus;
6140 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006141 cpu_set_t *cpu_set = NULL;
6142 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006143
Larry Hastings2f936352014-08-05 14:04:04 +10006144 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006145 if (iterator == NULL)
6146 return NULL;
6147
6148 ncpus = NCPUS_START;
6149 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006150 cpu_set = CPU_ALLOC(ncpus);
6151 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006152 PyErr_NoMemory();
6153 goto error;
6154 }
Larry Hastings2f936352014-08-05 14:04:04 +10006155 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006156
6157 while ((item = PyIter_Next(iterator))) {
6158 long cpu;
6159 if (!PyLong_Check(item)) {
6160 PyErr_Format(PyExc_TypeError,
6161 "expected an iterator of ints, "
6162 "but iterator yielded %R",
6163 Py_TYPE(item));
6164 Py_DECREF(item);
6165 goto error;
6166 }
6167 cpu = PyLong_AsLong(item);
6168 Py_DECREF(item);
6169 if (cpu < 0) {
6170 if (!PyErr_Occurred())
6171 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6172 goto error;
6173 }
6174 if (cpu > INT_MAX - 1) {
6175 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6176 goto error;
6177 }
6178 if (cpu >= ncpus) {
6179 /* Grow CPU mask to fit the CPU number */
6180 int newncpus = ncpus;
6181 cpu_set_t *newmask;
6182 size_t newsetsize;
6183 while (newncpus <= cpu) {
6184 if (newncpus > INT_MAX / 2)
6185 newncpus = cpu + 1;
6186 else
6187 newncpus = newncpus * 2;
6188 }
6189 newmask = CPU_ALLOC(newncpus);
6190 if (newmask == NULL) {
6191 PyErr_NoMemory();
6192 goto error;
6193 }
6194 newsetsize = CPU_ALLOC_SIZE(newncpus);
6195 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006196 memcpy(newmask, cpu_set, setsize);
6197 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006198 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006199 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006200 ncpus = newncpus;
6201 }
Larry Hastings2f936352014-08-05 14:04:04 +10006202 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006203 }
6204 Py_CLEAR(iterator);
6205
Larry Hastings2f936352014-08-05 14:04:04 +10006206 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006207 posix_error();
6208 goto error;
6209 }
Larry Hastings2f936352014-08-05 14:04:04 +10006210 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006211 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006212
6213error:
Larry Hastings2f936352014-08-05 14:04:04 +10006214 if (cpu_set)
6215 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006216 Py_XDECREF(iterator);
6217 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006218}
6219
Larry Hastings2f936352014-08-05 14:04:04 +10006220
6221/*[clinic input]
6222os.sched_getaffinity
6223 pid: pid_t
6224 /
6225
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006226Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006227
6228The affinity is returned as a set of CPU identifiers.
6229[clinic start generated code]*/
6230
Larry Hastings2f936352014-08-05 14:04:04 +10006231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006232os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006233/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006234{
Antoine Pitrou84869872012-08-04 16:16:35 +02006235 int cpu, ncpus, count;
6236 size_t setsize;
6237 cpu_set_t *mask = NULL;
6238 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006239
Antoine Pitrou84869872012-08-04 16:16:35 +02006240 ncpus = NCPUS_START;
6241 while (1) {
6242 setsize = CPU_ALLOC_SIZE(ncpus);
6243 mask = CPU_ALLOC(ncpus);
6244 if (mask == NULL)
6245 return PyErr_NoMemory();
6246 if (sched_getaffinity(pid, setsize, mask) == 0)
6247 break;
6248 CPU_FREE(mask);
6249 if (errno != EINVAL)
6250 return posix_error();
6251 if (ncpus > INT_MAX / 2) {
6252 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6253 "a large enough CPU set");
6254 return NULL;
6255 }
6256 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006257 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006258
6259 res = PySet_New(NULL);
6260 if (res == NULL)
6261 goto error;
6262 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6263 if (CPU_ISSET_S(cpu, setsize, mask)) {
6264 PyObject *cpu_num = PyLong_FromLong(cpu);
6265 --count;
6266 if (cpu_num == NULL)
6267 goto error;
6268 if (PySet_Add(res, cpu_num)) {
6269 Py_DECREF(cpu_num);
6270 goto error;
6271 }
6272 Py_DECREF(cpu_num);
6273 }
6274 }
6275 CPU_FREE(mask);
6276 return res;
6277
6278error:
6279 if (mask)
6280 CPU_FREE(mask);
6281 Py_XDECREF(res);
6282 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006283}
6284
Benjamin Peterson2740af82011-08-02 17:41:34 -05006285#endif /* HAVE_SCHED_SETAFFINITY */
6286
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006287#endif /* HAVE_SCHED_H */
6288
Larry Hastings2f936352014-08-05 14:04:04 +10006289
Neal Norwitzb59798b2003-03-21 01:43:31 +00006290/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006291/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6292#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006293#define DEV_PTY_FILE "/dev/ptc"
6294#define HAVE_DEV_PTMX
6295#else
6296#define DEV_PTY_FILE "/dev/ptmx"
6297#endif
6298
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006299#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006300#ifdef HAVE_PTY_H
6301#include <pty.h>
6302#else
6303#ifdef HAVE_LIBUTIL_H
6304#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006305#else
6306#ifdef HAVE_UTIL_H
6307#include <util.h>
6308#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006309#endif /* HAVE_LIBUTIL_H */
6310#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006311#ifdef HAVE_STROPTS_H
6312#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006313#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006314#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006315
Larry Hastings2f936352014-08-05 14:04:04 +10006316
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006317#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006318/*[clinic input]
6319os.openpty
6320
6321Open a pseudo-terminal.
6322
6323Return a tuple of (master_fd, slave_fd) containing open file descriptors
6324for both the master and slave ends.
6325[clinic start generated code]*/
6326
Larry Hastings2f936352014-08-05 14:04:04 +10006327static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006328os_openpty_impl(PyObject *module)
6329/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006330{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006331 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006332#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006333 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006334#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006335#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006337#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006339#endif
6340#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006341
Thomas Wouters70c21a12000-07-14 14:28:33 +00006342#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006344 goto posix_error;
6345
6346 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6347 goto error;
6348 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6349 goto error;
6350
Neal Norwitzb59798b2003-03-21 01:43:31 +00006351#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6353 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006354 goto posix_error;
6355 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6356 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006357
Victor Stinnerdaf45552013-08-28 00:53:59 +02006358 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006360 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006361
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006362#else
Victor Stinner000de532013-11-25 23:19:58 +01006363 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006365 goto posix_error;
6366
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006368
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 /* change permission of slave */
6370 if (grantpt(master_fd) < 0) {
6371 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006372 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006374
Victor Stinner8c62be82010-05-06 00:08:46 +00006375 /* unlock slave */
6376 if (unlockpt(master_fd) < 0) {
6377 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006378 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006380
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006382
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 slave_name = ptsname(master_fd); /* get name of slave */
6384 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006385 goto posix_error;
6386
6387 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006388 if (slave_fd == -1)
6389 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006390
6391 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6392 goto posix_error;
6393
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006394#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6396 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006397#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006399#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006400#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006401#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006402
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006404
Victor Stinnerdaf45552013-08-28 00:53:59 +02006405posix_error:
6406 posix_error();
6407error:
6408 if (master_fd != -1)
6409 close(master_fd);
6410 if (slave_fd != -1)
6411 close(slave_fd);
6412 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006413}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006414#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006415
Larry Hastings2f936352014-08-05 14:04:04 +10006416
Fred Drake8cef4cf2000-06-28 16:40:38 +00006417#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006418/*[clinic input]
6419os.forkpty
6420
6421Fork a new process with a new pseudo-terminal as controlling tty.
6422
6423Returns a tuple of (pid, master_fd).
6424Like fork(), return pid of 0 to the child process,
6425and pid of child to the parent process.
6426To both, return fd of newly opened pseudo-terminal.
6427[clinic start generated code]*/
6428
Larry Hastings2f936352014-08-05 14:04:04 +10006429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006430os_forkpty_impl(PyObject *module)
6431/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006432{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006433 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006435
Eric Snow59032962018-09-14 14:17:20 -07006436 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6437 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6438 return NULL;
6439 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006440 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 pid = forkpty(&master_fd, NULL, NULL, NULL);
6442 if (pid == 0) {
6443 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006444 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 } else {
6446 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006447 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 }
6449 if (pid == -1)
6450 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006452}
Larry Hastings2f936352014-08-05 14:04:04 +10006453#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006454
Ross Lagerwall7807c352011-03-17 20:20:30 +02006455
Guido van Rossumad0ee831995-03-01 10:34:45 +00006456#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006457/*[clinic input]
6458os.getegid
6459
6460Return the current process's effective group id.
6461[clinic start generated code]*/
6462
Larry Hastings2f936352014-08-05 14:04:04 +10006463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006464os_getegid_impl(PyObject *module)
6465/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006466{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006467 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006468}
Larry Hastings2f936352014-08-05 14:04:04 +10006469#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Guido van Rossumad0ee831995-03-01 10:34:45 +00006472#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006473/*[clinic input]
6474os.geteuid
6475
6476Return the current process's effective user id.
6477[clinic start generated code]*/
6478
Larry Hastings2f936352014-08-05 14:04:04 +10006479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006480os_geteuid_impl(PyObject *module)
6481/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006482{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006483 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006484}
Larry Hastings2f936352014-08-05 14:04:04 +10006485#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006486
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006487
Guido van Rossumad0ee831995-03-01 10:34:45 +00006488#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006489/*[clinic input]
6490os.getgid
6491
6492Return the current process's group id.
6493[clinic start generated code]*/
6494
Larry Hastings2f936352014-08-05 14:04:04 +10006495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006496os_getgid_impl(PyObject *module)
6497/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006498{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006499 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006500}
Larry Hastings2f936352014-08-05 14:04:04 +10006501#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006503
Berker Peksag39404992016-09-15 20:45:16 +03006504#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006505/*[clinic input]
6506os.getpid
6507
6508Return the current process id.
6509[clinic start generated code]*/
6510
Larry Hastings2f936352014-08-05 14:04:04 +10006511static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006512os_getpid_impl(PyObject *module)
6513/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006514{
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006516}
Berker Peksag39404992016-09-15 20:45:16 +03006517#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006518
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006519#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006520
6521/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006522PyDoc_STRVAR(posix_getgrouplist__doc__,
6523"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6524Returns a list of groups to which a user belongs.\n\n\
6525 user: username to lookup\n\
6526 group: base group id of the user");
6527
6528static PyObject *
6529posix_getgrouplist(PyObject *self, PyObject *args)
6530{
6531#ifdef NGROUPS_MAX
6532#define MAX_GROUPS NGROUPS_MAX
6533#else
6534 /* defined to be 16 on Solaris7, so this should be a small number */
6535#define MAX_GROUPS 64
6536#endif
6537
6538 const char *user;
6539 int i, ngroups;
6540 PyObject *list;
6541#ifdef __APPLE__
6542 int *groups, basegid;
6543#else
6544 gid_t *groups, basegid;
6545#endif
6546 ngroups = MAX_GROUPS;
6547
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006548#ifdef __APPLE__
6549 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006550 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006551#else
6552 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6553 _Py_Gid_Converter, &basegid))
6554 return NULL;
6555#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006556
6557#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006558 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006559#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006560 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006561#endif
6562 if (groups == NULL)
6563 return PyErr_NoMemory();
6564
6565 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6566 PyMem_Del(groups);
6567 return posix_error();
6568 }
6569
6570 list = PyList_New(ngroups);
6571 if (list == NULL) {
6572 PyMem_Del(groups);
6573 return NULL;
6574 }
6575
6576 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006577#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006578 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006579#else
6580 PyObject *o = _PyLong_FromGid(groups[i]);
6581#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006582 if (o == NULL) {
6583 Py_DECREF(list);
6584 PyMem_Del(groups);
6585 return NULL;
6586 }
6587 PyList_SET_ITEM(list, i, o);
6588 }
6589
6590 PyMem_Del(groups);
6591
6592 return list;
6593}
Larry Hastings2f936352014-08-05 14:04:04 +10006594#endif /* HAVE_GETGROUPLIST */
6595
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006596
Fred Drakec9680921999-12-13 16:37:25 +00006597#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006598/*[clinic input]
6599os.getgroups
6600
6601Return list of supplemental group IDs for the process.
6602[clinic start generated code]*/
6603
Larry Hastings2f936352014-08-05 14:04:04 +10006604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006605os_getgroups_impl(PyObject *module)
6606/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006607{
6608 PyObject *result = NULL;
6609
Fred Drakec9680921999-12-13 16:37:25 +00006610#ifdef NGROUPS_MAX
6611#define MAX_GROUPS NGROUPS_MAX
6612#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006614#define MAX_GROUPS 64
6615#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006617
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006618 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006619 * This is a helper variable to store the intermediate result when
6620 * that happens.
6621 *
6622 * To keep the code readable the OSX behaviour is unconditional,
6623 * according to the POSIX spec this should be safe on all unix-y
6624 * systems.
6625 */
6626 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006628
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006629#ifdef __APPLE__
6630 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6631 * there are more groups than can fit in grouplist. Therefore, on OS X
6632 * always first call getgroups with length 0 to get the actual number
6633 * of groups.
6634 */
6635 n = getgroups(0, NULL);
6636 if (n < 0) {
6637 return posix_error();
6638 } else if (n <= MAX_GROUPS) {
6639 /* groups will fit in existing array */
6640 alt_grouplist = grouplist;
6641 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006642 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006643 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006644 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006645 }
6646 }
6647
6648 n = getgroups(n, alt_grouplist);
6649 if (n == -1) {
6650 if (alt_grouplist != grouplist) {
6651 PyMem_Free(alt_grouplist);
6652 }
6653 return posix_error();
6654 }
6655#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006657 if (n < 0) {
6658 if (errno == EINVAL) {
6659 n = getgroups(0, NULL);
6660 if (n == -1) {
6661 return posix_error();
6662 }
6663 if (n == 0) {
6664 /* Avoid malloc(0) */
6665 alt_grouplist = grouplist;
6666 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006667 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006668 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006669 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006670 }
6671 n = getgroups(n, alt_grouplist);
6672 if (n == -1) {
6673 PyMem_Free(alt_grouplist);
6674 return posix_error();
6675 }
6676 }
6677 } else {
6678 return posix_error();
6679 }
6680 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006681#endif
6682
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006683 result = PyList_New(n);
6684 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 int i;
6686 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006687 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006689 Py_DECREF(result);
6690 result = NULL;
6691 break;
Fred Drakec9680921999-12-13 16:37:25 +00006692 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006694 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006695 }
6696
6697 if (alt_grouplist != grouplist) {
6698 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006700
Fred Drakec9680921999-12-13 16:37:25 +00006701 return result;
6702}
Larry Hastings2f936352014-08-05 14:04:04 +10006703#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006704
Antoine Pitroub7572f02009-12-02 20:46:48 +00006705#ifdef HAVE_INITGROUPS
6706PyDoc_STRVAR(posix_initgroups__doc__,
6707"initgroups(username, gid) -> None\n\n\
6708Call the system initgroups() to initialize the group access list with all of\n\
6709the groups of which the specified username is a member, plus the specified\n\
6710group id.");
6711
Larry Hastings2f936352014-08-05 14:04:04 +10006712/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006713static PyObject *
6714posix_initgroups(PyObject *self, PyObject *args)
6715{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006716 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006717 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006718 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006719#ifdef __APPLE__
6720 int gid;
6721#else
6722 gid_t gid;
6723#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006724
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006725#ifdef __APPLE__
6726 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6727 PyUnicode_FSConverter, &oname,
6728 &gid))
6729#else
6730 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6731 PyUnicode_FSConverter, &oname,
6732 _Py_Gid_Converter, &gid))
6733#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006735 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006736
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006737 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006738 Py_DECREF(oname);
6739 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006741
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006742 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006743}
Larry Hastings2f936352014-08-05 14:04:04 +10006744#endif /* HAVE_INITGROUPS */
6745
Antoine Pitroub7572f02009-12-02 20:46:48 +00006746
Martin v. Löwis606edc12002-06-13 21:09:11 +00006747#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006748/*[clinic input]
6749os.getpgid
6750
6751 pid: pid_t
6752
6753Call the system call getpgid(), and return the result.
6754[clinic start generated code]*/
6755
Larry Hastings2f936352014-08-05 14:04:04 +10006756static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006757os_getpgid_impl(PyObject *module, pid_t pid)
6758/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006759{
6760 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (pgid < 0)
6762 return posix_error();
6763 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006764}
6765#endif /* HAVE_GETPGID */
6766
6767
Guido van Rossumb6775db1994-08-01 11:34:53 +00006768#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006769/*[clinic input]
6770os.getpgrp
6771
6772Return the current process group id.
6773[clinic start generated code]*/
6774
Larry Hastings2f936352014-08-05 14:04:04 +10006775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006776os_getpgrp_impl(PyObject *module)
6777/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006778{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006779#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006781#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006783#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006784}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006785#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006787
Guido van Rossumb6775db1994-08-01 11:34:53 +00006788#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006789/*[clinic input]
6790os.setpgrp
6791
6792Make the current process the leader of its process group.
6793[clinic start generated code]*/
6794
Larry Hastings2f936352014-08-05 14:04:04 +10006795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006796os_setpgrp_impl(PyObject *module)
6797/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006798{
Guido van Rossum64933891994-10-20 21:56:42 +00006799#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006801#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006803#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006805 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006806}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006807#endif /* HAVE_SETPGRP */
6808
Guido van Rossumad0ee831995-03-01 10:34:45 +00006809#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006810
6811#ifdef MS_WINDOWS
6812#include <tlhelp32.h>
6813
6814static PyObject*
6815win32_getppid()
6816{
6817 HANDLE snapshot;
6818 pid_t mypid;
6819 PyObject* result = NULL;
6820 BOOL have_record;
6821 PROCESSENTRY32 pe;
6822
6823 mypid = getpid(); /* This function never fails */
6824
6825 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6826 if (snapshot == INVALID_HANDLE_VALUE)
6827 return PyErr_SetFromWindowsErr(GetLastError());
6828
6829 pe.dwSize = sizeof(pe);
6830 have_record = Process32First(snapshot, &pe);
6831 while (have_record) {
6832 if (mypid == (pid_t)pe.th32ProcessID) {
6833 /* We could cache the ulong value in a static variable. */
6834 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6835 break;
6836 }
6837
6838 have_record = Process32Next(snapshot, &pe);
6839 }
6840
6841 /* If our loop exits and our pid was not found (result will be NULL)
6842 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6843 * error anyway, so let's raise it. */
6844 if (!result)
6845 result = PyErr_SetFromWindowsErr(GetLastError());
6846
6847 CloseHandle(snapshot);
6848
6849 return result;
6850}
6851#endif /*MS_WINDOWS*/
6852
Larry Hastings2f936352014-08-05 14:04:04 +10006853
6854/*[clinic input]
6855os.getppid
6856
6857Return the parent's process id.
6858
6859If the parent process has already exited, Windows machines will still
6860return its id; others systems will return the id of the 'init' process (1).
6861[clinic start generated code]*/
6862
Larry Hastings2f936352014-08-05 14:04:04 +10006863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006864os_getppid_impl(PyObject *module)
6865/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006866{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006867#ifdef MS_WINDOWS
6868 return win32_getppid();
6869#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006871#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006872}
6873#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006875
Fred Drake12c6e2d1999-12-14 21:25:03 +00006876#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006877/*[clinic input]
6878os.getlogin
6879
6880Return the actual login name.
6881[clinic start generated code]*/
6882
Larry Hastings2f936352014-08-05 14:04:04 +10006883static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006884os_getlogin_impl(PyObject *module)
6885/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006886{
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006888#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006889 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006890 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006891
6892 if (GetUserNameW(user_name, &num_chars)) {
6893 /* num_chars is the number of unicode chars plus null terminator */
6894 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006895 }
6896 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006897 result = PyErr_SetFromWindowsErr(GetLastError());
6898#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 char *name;
6900 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006901
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 errno = 0;
6903 name = getlogin();
6904 if (name == NULL) {
6905 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006906 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006907 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006908 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 }
6910 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006911 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006913#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006914 return result;
6915}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006916#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006917
Larry Hastings2f936352014-08-05 14:04:04 +10006918
Guido van Rossumad0ee831995-03-01 10:34:45 +00006919#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006920/*[clinic input]
6921os.getuid
6922
6923Return the current process's user id.
6924[clinic start generated code]*/
6925
Larry Hastings2f936352014-08-05 14:04:04 +10006926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006927os_getuid_impl(PyObject *module)
6928/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006929{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006930 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006931}
Larry Hastings2f936352014-08-05 14:04:04 +10006932#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006934
Brian Curtineb24d742010-04-12 17:16:38 +00006935#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006936#define HAVE_KILL
6937#endif /* MS_WINDOWS */
6938
6939#ifdef HAVE_KILL
6940/*[clinic input]
6941os.kill
6942
6943 pid: pid_t
6944 signal: Py_ssize_t
6945 /
6946
6947Kill a process with a signal.
6948[clinic start generated code]*/
6949
Larry Hastings2f936352014-08-05 14:04:04 +10006950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006951os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6952/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006953#ifndef MS_WINDOWS
6954{
6955 if (kill(pid, (int)signal) == -1)
6956 return posix_error();
6957 Py_RETURN_NONE;
6958}
6959#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006960{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006961 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006962 DWORD sig = (DWORD)signal;
6963 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006965
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 /* Console processes which share a common console can be sent CTRL+C or
6967 CTRL+BREAK events, provided they handle said events. */
6968 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006969 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 err = GetLastError();
6971 PyErr_SetFromWindowsErr(err);
6972 }
6973 else
6974 Py_RETURN_NONE;
6975 }
Brian Curtineb24d742010-04-12 17:16:38 +00006976
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6978 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006979 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 if (handle == NULL) {
6981 err = GetLastError();
6982 return PyErr_SetFromWindowsErr(err);
6983 }
Brian Curtineb24d742010-04-12 17:16:38 +00006984
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 if (TerminateProcess(handle, sig) == 0) {
6986 err = GetLastError();
6987 result = PyErr_SetFromWindowsErr(err);
6988 } else {
6989 Py_INCREF(Py_None);
6990 result = Py_None;
6991 }
Brian Curtineb24d742010-04-12 17:16:38 +00006992
Victor Stinner8c62be82010-05-06 00:08:46 +00006993 CloseHandle(handle);
6994 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006995}
Larry Hastings2f936352014-08-05 14:04:04 +10006996#endif /* !MS_WINDOWS */
6997#endif /* HAVE_KILL */
6998
6999
7000#ifdef HAVE_KILLPG
7001/*[clinic input]
7002os.killpg
7003
7004 pgid: pid_t
7005 signal: int
7006 /
7007
7008Kill a process group with a signal.
7009[clinic start generated code]*/
7010
Larry Hastings2f936352014-08-05 14:04:04 +10007011static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007012os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7013/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007014{
7015 /* XXX some man pages make the `pgid` parameter an int, others
7016 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7017 take the same type. Moreover, pid_t is always at least as wide as
7018 int (else compilation of this module fails), which is safe. */
7019 if (killpg(pgid, signal) == -1)
7020 return posix_error();
7021 Py_RETURN_NONE;
7022}
7023#endif /* HAVE_KILLPG */
7024
Brian Curtineb24d742010-04-12 17:16:38 +00007025
Guido van Rossumc0125471996-06-28 18:55:32 +00007026#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007027#ifdef HAVE_SYS_LOCK_H
7028#include <sys/lock.h>
7029#endif
7030
Larry Hastings2f936352014-08-05 14:04:04 +10007031/*[clinic input]
7032os.plock
7033 op: int
7034 /
7035
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007037[clinic start generated code]*/
7038
Larry Hastings2f936352014-08-05 14:04:04 +10007039static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007040os_plock_impl(PyObject *module, int op)
7041/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007042{
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 if (plock(op) == -1)
7044 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007045 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007046}
Larry Hastings2f936352014-08-05 14:04:04 +10007047#endif /* HAVE_PLOCK */
7048
Guido van Rossumc0125471996-06-28 18:55:32 +00007049
Guido van Rossumb6775db1994-08-01 11:34:53 +00007050#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007051/*[clinic input]
7052os.setuid
7053
7054 uid: uid_t
7055 /
7056
7057Set the current process's user id.
7058[clinic start generated code]*/
7059
Larry Hastings2f936352014-08-05 14:04:04 +10007060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007061os_setuid_impl(PyObject *module, uid_t uid)
7062/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007063{
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 if (setuid(uid) < 0)
7065 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007066 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007067}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007068#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007070
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007071#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007072/*[clinic input]
7073os.seteuid
7074
7075 euid: uid_t
7076 /
7077
7078Set the current process's effective user id.
7079[clinic start generated code]*/
7080
Larry Hastings2f936352014-08-05 14:04:04 +10007081static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007082os_seteuid_impl(PyObject *module, uid_t euid)
7083/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007084{
7085 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007086 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007087 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007088}
7089#endif /* HAVE_SETEUID */
7090
Larry Hastings2f936352014-08-05 14:04:04 +10007091
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007092#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007093/*[clinic input]
7094os.setegid
7095
7096 egid: gid_t
7097 /
7098
7099Set the current process's effective group id.
7100[clinic start generated code]*/
7101
Larry Hastings2f936352014-08-05 14:04:04 +10007102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007103os_setegid_impl(PyObject *module, gid_t egid)
7104/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007105{
7106 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007107 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007108 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007109}
7110#endif /* HAVE_SETEGID */
7111
Larry Hastings2f936352014-08-05 14:04:04 +10007112
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007113#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007114/*[clinic input]
7115os.setreuid
7116
7117 ruid: uid_t
7118 euid: uid_t
7119 /
7120
7121Set the current process's real and effective user ids.
7122[clinic start generated code]*/
7123
Larry Hastings2f936352014-08-05 14:04:04 +10007124static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007125os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7126/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007127{
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 if (setreuid(ruid, euid) < 0) {
7129 return posix_error();
7130 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007131 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007133}
7134#endif /* HAVE_SETREUID */
7135
Larry Hastings2f936352014-08-05 14:04:04 +10007136
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007137#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007138/*[clinic input]
7139os.setregid
7140
7141 rgid: gid_t
7142 egid: gid_t
7143 /
7144
7145Set the current process's real and effective group ids.
7146[clinic start generated code]*/
7147
Larry Hastings2f936352014-08-05 14:04:04 +10007148static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007149os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7150/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007151{
7152 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007154 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007155}
7156#endif /* HAVE_SETREGID */
7157
Larry Hastings2f936352014-08-05 14:04:04 +10007158
Guido van Rossumb6775db1994-08-01 11:34:53 +00007159#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007160/*[clinic input]
7161os.setgid
7162 gid: gid_t
7163 /
7164
7165Set the current process's group id.
7166[clinic start generated code]*/
7167
Larry Hastings2f936352014-08-05 14:04:04 +10007168static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007169os_setgid_impl(PyObject *module, gid_t gid)
7170/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007171{
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 if (setgid(gid) < 0)
7173 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007174 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007175}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007176#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007177
Larry Hastings2f936352014-08-05 14:04:04 +10007178
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007179#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007180/*[clinic input]
7181os.setgroups
7182
7183 groups: object
7184 /
7185
7186Set the groups of the current process to list.
7187[clinic start generated code]*/
7188
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007190os_setgroups(PyObject *module, PyObject *groups)
7191/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007192{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007193 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007194 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007195
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 if (!PySequence_Check(groups)) {
7197 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7198 return NULL;
7199 }
7200 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007201 if (len < 0) {
7202 return NULL;
7203 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 if (len > MAX_GROUPS) {
7205 PyErr_SetString(PyExc_ValueError, "too many groups");
7206 return NULL;
7207 }
7208 for(i = 0; i < len; i++) {
7209 PyObject *elem;
7210 elem = PySequence_GetItem(groups, i);
7211 if (!elem)
7212 return NULL;
7213 if (!PyLong_Check(elem)) {
7214 PyErr_SetString(PyExc_TypeError,
7215 "groups must be integers");
7216 Py_DECREF(elem);
7217 return NULL;
7218 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007219 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 Py_DECREF(elem);
7221 return NULL;
7222 }
7223 }
7224 Py_DECREF(elem);
7225 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007226
Victor Stinner8c62be82010-05-06 00:08:46 +00007227 if (setgroups(len, grouplist) < 0)
7228 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007229 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007230}
7231#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007232
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007233#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7234static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007235wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007236{
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 PyObject *result;
7238 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007239 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007240
Victor Stinner8c62be82010-05-06 00:08:46 +00007241 if (pid == -1)
7242 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007243
Victor Stinner8c62be82010-05-06 00:08:46 +00007244 if (struct_rusage == NULL) {
7245 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7246 if (m == NULL)
7247 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007248 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 Py_DECREF(m);
7250 if (struct_rusage == NULL)
7251 return NULL;
7252 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007253
Victor Stinner8c62be82010-05-06 00:08:46 +00007254 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7255 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7256 if (!result)
7257 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007258
7259#ifndef doubletime
7260#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7261#endif
7262
Victor Stinner8c62be82010-05-06 00:08:46 +00007263 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007264 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007265 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007266 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007267#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7269 SET_INT(result, 2, ru->ru_maxrss);
7270 SET_INT(result, 3, ru->ru_ixrss);
7271 SET_INT(result, 4, ru->ru_idrss);
7272 SET_INT(result, 5, ru->ru_isrss);
7273 SET_INT(result, 6, ru->ru_minflt);
7274 SET_INT(result, 7, ru->ru_majflt);
7275 SET_INT(result, 8, ru->ru_nswap);
7276 SET_INT(result, 9, ru->ru_inblock);
7277 SET_INT(result, 10, ru->ru_oublock);
7278 SET_INT(result, 11, ru->ru_msgsnd);
7279 SET_INT(result, 12, ru->ru_msgrcv);
7280 SET_INT(result, 13, ru->ru_nsignals);
7281 SET_INT(result, 14, ru->ru_nvcsw);
7282 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007283#undef SET_INT
7284
Victor Stinner8c62be82010-05-06 00:08:46 +00007285 if (PyErr_Occurred()) {
7286 Py_DECREF(result);
7287 return NULL;
7288 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007289
Victor Stinner8c62be82010-05-06 00:08:46 +00007290 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007291}
7292#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7293
Larry Hastings2f936352014-08-05 14:04:04 +10007294
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007295#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007296/*[clinic input]
7297os.wait3
7298
7299 options: int
7300Wait for completion of a child process.
7301
7302Returns a tuple of information about the child process:
7303 (pid, status, rusage)
7304[clinic start generated code]*/
7305
Larry Hastings2f936352014-08-05 14:04:04 +10007306static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007307os_wait3_impl(PyObject *module, int options)
7308/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007309{
Victor Stinner8c62be82010-05-06 00:08:46 +00007310 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007311 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007312 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 WAIT_TYPE status;
7314 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007315
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007316 do {
7317 Py_BEGIN_ALLOW_THREADS
7318 pid = wait3(&status, options, &ru);
7319 Py_END_ALLOW_THREADS
7320 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7321 if (pid < 0)
7322 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007323
Victor Stinner4195b5c2012-02-08 23:03:19 +01007324 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007325}
7326#endif /* HAVE_WAIT3 */
7327
Larry Hastings2f936352014-08-05 14:04:04 +10007328
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007329#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007330/*[clinic input]
7331
7332os.wait4
7333
7334 pid: pid_t
7335 options: int
7336
7337Wait for completion of a specific child process.
7338
7339Returns a tuple of information about the child process:
7340 (pid, status, rusage)
7341[clinic start generated code]*/
7342
Larry Hastings2f936352014-08-05 14:04:04 +10007343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007344os_wait4_impl(PyObject *module, pid_t pid, int options)
7345/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007346{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007347 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007348 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007349 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007350 WAIT_TYPE status;
7351 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007352
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007353 do {
7354 Py_BEGIN_ALLOW_THREADS
7355 res = wait4(pid, &status, options, &ru);
7356 Py_END_ALLOW_THREADS
7357 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7358 if (res < 0)
7359 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007360
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007361 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007362}
7363#endif /* HAVE_WAIT4 */
7364
Larry Hastings2f936352014-08-05 14:04:04 +10007365
Ross Lagerwall7807c352011-03-17 20:20:30 +02007366#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007367/*[clinic input]
7368os.waitid
7369
7370 idtype: idtype_t
7371 Must be one of be P_PID, P_PGID or P_ALL.
7372 id: id_t
7373 The id to wait on.
7374 options: int
7375 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7376 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7377 /
7378
7379Returns the result of waiting for a process or processes.
7380
7381Returns either waitid_result or None if WNOHANG is specified and there are
7382no children in a waitable state.
7383[clinic start generated code]*/
7384
Larry Hastings2f936352014-08-05 14:04:04 +10007385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007386os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7387/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007388{
7389 PyObject *result;
7390 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007391 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007392 siginfo_t si;
7393 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007394
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007395 do {
7396 Py_BEGIN_ALLOW_THREADS
7397 res = waitid(idtype, id, &si, options);
7398 Py_END_ALLOW_THREADS
7399 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7400 if (res < 0)
7401 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007402
7403 if (si.si_pid == 0)
7404 Py_RETURN_NONE;
7405
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007406 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007407 if (!result)
7408 return NULL;
7409
7410 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007411 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007412 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7413 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7414 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7415 if (PyErr_Occurred()) {
7416 Py_DECREF(result);
7417 return NULL;
7418 }
7419
7420 return result;
7421}
Larry Hastings2f936352014-08-05 14:04:04 +10007422#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007423
Larry Hastings2f936352014-08-05 14:04:04 +10007424
7425#if defined(HAVE_WAITPID)
7426/*[clinic input]
7427os.waitpid
7428 pid: pid_t
7429 options: int
7430 /
7431
7432Wait for completion of a given child process.
7433
7434Returns a tuple of information regarding the child process:
7435 (pid, status)
7436
7437The options argument is ignored on Windows.
7438[clinic start generated code]*/
7439
Larry Hastings2f936352014-08-05 14:04:04 +10007440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007441os_waitpid_impl(PyObject *module, pid_t pid, int options)
7442/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007443{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007444 pid_t res;
7445 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007446 WAIT_TYPE status;
7447 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007448
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007449 do {
7450 Py_BEGIN_ALLOW_THREADS
7451 res = waitpid(pid, &status, options);
7452 Py_END_ALLOW_THREADS
7453 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7454 if (res < 0)
7455 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007456
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007457 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007458}
Tim Petersab034fa2002-02-01 11:27:43 +00007459#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007460/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007461/*[clinic input]
7462os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007463 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007464 options: int
7465 /
7466
7467Wait for completion of a given process.
7468
7469Returns a tuple of information regarding the process:
7470 (pid, status << 8)
7471
7472The options argument is ignored on Windows.
7473[clinic start generated code]*/
7474
Larry Hastings2f936352014-08-05 14:04:04 +10007475static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007476os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007477/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007478{
7479 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007480 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007481 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007482
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007483 do {
7484 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007485 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007486 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007487 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007488 Py_END_ALLOW_THREADS
7489 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007490 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007491 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007492
Victor Stinner8c62be82010-05-06 00:08:46 +00007493 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007494 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007495}
Larry Hastings2f936352014-08-05 14:04:04 +10007496#endif
7497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007498
Guido van Rossumad0ee831995-03-01 10:34:45 +00007499#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007500/*[clinic input]
7501os.wait
7502
7503Wait for completion of a child process.
7504
7505Returns a tuple of information about the child process:
7506 (pid, status)
7507[clinic start generated code]*/
7508
Larry Hastings2f936352014-08-05 14:04:04 +10007509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007510os_wait_impl(PyObject *module)
7511/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007512{
Victor Stinner8c62be82010-05-06 00:08:46 +00007513 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007514 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007515 WAIT_TYPE status;
7516 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007517
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007518 do {
7519 Py_BEGIN_ALLOW_THREADS
7520 pid = wait(&status);
7521 Py_END_ALLOW_THREADS
7522 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7523 if (pid < 0)
7524 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007525
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007527}
Larry Hastings2f936352014-08-05 14:04:04 +10007528#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007530
Larry Hastings9cf065c2012-06-22 16:30:09 -07007531#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007532/*[clinic input]
7533os.readlink
7534
7535 path: path_t
7536 *
7537 dir_fd: dir_fd(requires='readlinkat') = None
7538
7539Return a string representing the path to which the symbolic link points.
7540
7541If dir_fd is not None, it should be a file descriptor open to a directory,
7542and path should be relative; path will then be relative to that directory.
7543
7544dir_fd may not be implemented on your platform. If it is unavailable,
7545using it will raise a NotImplementedError.
7546[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007547
Barry Warsaw53699e91996-12-10 23:23:01 +00007548static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007549os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7550/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007551{
Berker Peksage0b5b202018-08-15 13:03:41 +03007552#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007553 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007554 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007555
7556 Py_BEGIN_ALLOW_THREADS
7557#ifdef HAVE_READLINKAT
7558 if (dir_fd != DEFAULT_DIR_FD)
7559 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7560 else
7561#endif
7562 length = readlink(path->narrow, buffer, MAXPATHLEN);
7563 Py_END_ALLOW_THREADS
7564
7565 if (length < 0) {
7566 return path_error(path);
7567 }
7568 buffer[length] = '\0';
7569
7570 if (PyUnicode_Check(path->object))
7571 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7572 else
7573 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007574#elif defined(MS_WINDOWS)
7575 DWORD n_bytes_returned;
7576 DWORD io_result;
7577 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007578 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7579 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7580 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007581 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007582
Larry Hastings2f936352014-08-05 14:04:04 +10007583 /* First get a handle to the reparse point */
7584 Py_BEGIN_ALLOW_THREADS
7585 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007586 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007587 0,
7588 0,
7589 0,
7590 OPEN_EXISTING,
7591 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7592 0);
7593 Py_END_ALLOW_THREADS
7594
Berker Peksage0b5b202018-08-15 13:03:41 +03007595 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007596 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007597 }
Larry Hastings2f936352014-08-05 14:04:04 +10007598
7599 Py_BEGIN_ALLOW_THREADS
7600 /* New call DeviceIoControl to read the reparse point */
7601 io_result = DeviceIoControl(
7602 reparse_point_handle,
7603 FSCTL_GET_REPARSE_POINT,
7604 0, 0, /* in buffer */
7605 target_buffer, sizeof(target_buffer),
7606 &n_bytes_returned,
7607 0 /* we're not using OVERLAPPED_IO */
7608 );
7609 CloseHandle(reparse_point_handle);
7610 Py_END_ALLOW_THREADS
7611
Berker Peksage0b5b202018-08-15 13:03:41 +03007612 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007613 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007614 }
Larry Hastings2f936352014-08-05 14:04:04 +10007615
7616 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7617 {
7618 PyErr_SetString(PyExc_ValueError,
7619 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007620 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007621 }
SSE43c34aad2018-02-13 00:10:35 +07007622 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7623 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007624
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007625 result = PyUnicode_FromWideChar(print_name,
7626 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7627 if (path->narrow) {
7628 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007629 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007630 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007631#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007632}
Berker Peksage0b5b202018-08-15 13:03:41 +03007633#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007634
Larry Hastings9cf065c2012-06-22 16:30:09 -07007635#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007636
7637#if defined(MS_WINDOWS)
7638
7639/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Steve Dower6921e732018-03-05 14:26:08 -08007640static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007641
Larry Hastings9cf065c2012-06-22 16:30:09 -07007642static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007643check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007644{
7645 HINSTANCE hKernel32;
7646 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007647 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007648 return 1;
7649 hKernel32 = GetModuleHandleW(L"KERNEL32");
7650 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7651 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007652 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007653}
7654
Steve Dower6921e732018-03-05 14:26:08 -08007655/* Remove the last portion of the path - return 0 on success */
7656static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007657_dirnameW(WCHAR *path)
7658{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007659 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007660 size_t length = wcsnlen_s(path, MAX_PATH);
7661 if (length == MAX_PATH) {
7662 return -1;
7663 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007664
7665 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007666 for(ptr = path + length; ptr != path; ptr--) {
7667 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007668 break;
Steve Dower6921e732018-03-05 14:26:08 -08007669 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007670 }
7671 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007672 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007673}
7674
Victor Stinner31b3b922013-06-05 01:49:17 +02007675/* Is this path absolute? */
7676static int
7677_is_absW(const WCHAR *path)
7678{
Steve Dower6921e732018-03-05 14:26:08 -08007679 return path[0] == L'\\' || path[0] == L'/' ||
7680 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007681}
7682
Steve Dower6921e732018-03-05 14:26:08 -08007683/* join root and rest with a backslash - return 0 on success */
7684static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007685_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7686{
Victor Stinner31b3b922013-06-05 01:49:17 +02007687 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007688 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007689 }
7690
Steve Dower6921e732018-03-05 14:26:08 -08007691 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7692 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007693 }
Steve Dower6921e732018-03-05 14:26:08 -08007694
7695 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7696 return -1;
7697 }
7698
7699 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007700}
7701
Victor Stinner31b3b922013-06-05 01:49:17 +02007702/* Return True if the path at src relative to dest is a directory */
7703static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007704_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007705{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007706 WIN32_FILE_ATTRIBUTE_DATA src_info;
7707 WCHAR dest_parent[MAX_PATH];
7708 WCHAR src_resolved[MAX_PATH] = L"";
7709
7710 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007711 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7712 _dirnameW(dest_parent)) {
7713 return 0;
7714 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007715 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007716 if (_joinW(src_resolved, dest_parent, src)) {
7717 return 0;
7718 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007719 return (
7720 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7721 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7722 );
7723}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007724#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007725
Larry Hastings2f936352014-08-05 14:04:04 +10007726
7727/*[clinic input]
7728os.symlink
7729 src: path_t
7730 dst: path_t
7731 target_is_directory: bool = False
7732 *
7733 dir_fd: dir_fd(requires='symlinkat')=None
7734
7735# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7736
7737Create a symbolic link pointing to src named dst.
7738
7739target_is_directory is required on Windows if the target is to be
7740 interpreted as a directory. (On Windows, symlink requires
7741 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7742 target_is_directory is ignored on non-Windows platforms.
7743
7744If dir_fd is not None, it should be a file descriptor open to a directory,
7745 and path should be relative; path will then be relative to that directory.
7746dir_fd may not be implemented on your platform.
7747 If it is unavailable, using it will raise a NotImplementedError.
7748
7749[clinic start generated code]*/
7750
Larry Hastings2f936352014-08-05 14:04:04 +10007751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007752os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007753 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007754/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007755{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007756#ifdef MS_WINDOWS
7757 DWORD result;
7758#else
7759 int result;
7760#endif
7761
Larry Hastings9cf065c2012-06-22 16:30:09 -07007762#ifdef MS_WINDOWS
7763 if (!check_CreateSymbolicLink()) {
7764 PyErr_SetString(PyExc_NotImplementedError,
7765 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007766 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007767 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007768 if (!win32_can_symlink) {
7769 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007770 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007771 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007772#endif
7773
Larry Hastings9cf065c2012-06-22 16:30:09 -07007774#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007775
Larry Hastings9cf065c2012-06-22 16:30:09 -07007776 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007777 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007778 /* if src is a directory, ensure target_is_directory==1 */
7779 target_is_directory |= _check_dirW(src->wide, dst->wide);
7780 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7781 target_is_directory);
Steve Dower6921e732018-03-05 14:26:08 -08007782 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007783 Py_END_ALLOW_THREADS
7784
Larry Hastings2f936352014-08-05 14:04:04 +10007785 if (!result)
7786 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007787
7788#else
7789
Steve Dower6921e732018-03-05 14:26:08 -08007790 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7791 PyErr_SetString(PyExc_ValueError,
7792 "symlink: src and dst must be the same type");
7793 return NULL;
7794 }
7795
Larry Hastings9cf065c2012-06-22 16:30:09 -07007796 Py_BEGIN_ALLOW_THREADS
7797#if HAVE_SYMLINKAT
7798 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007799 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007800 else
7801#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007802 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007803 Py_END_ALLOW_THREADS
7804
Larry Hastings2f936352014-08-05 14:04:04 +10007805 if (result)
7806 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007807#endif
7808
Larry Hastings2f936352014-08-05 14:04:04 +10007809 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007810}
7811#endif /* HAVE_SYMLINK */
7812
Larry Hastings9cf065c2012-06-22 16:30:09 -07007813
Brian Curtind40e6f72010-07-08 21:39:08 +00007814
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007815
Larry Hastings605a62d2012-06-24 04:33:36 -07007816static PyStructSequence_Field times_result_fields[] = {
7817 {"user", "user time"},
7818 {"system", "system time"},
7819 {"children_user", "user time of children"},
7820 {"children_system", "system time of children"},
7821 {"elapsed", "elapsed time since an arbitrary point in the past"},
7822 {NULL}
7823};
7824
7825PyDoc_STRVAR(times_result__doc__,
7826"times_result: Result from os.times().\n\n\
7827This object may be accessed either as a tuple of\n\
7828 (user, system, children_user, children_system, elapsed),\n\
7829or via the attributes user, system, children_user, children_system,\n\
7830and elapsed.\n\
7831\n\
7832See os.times for more information.");
7833
7834static PyStructSequence_Desc times_result_desc = {
7835 "times_result", /* name */
7836 times_result__doc__, /* doc */
7837 times_result_fields,
7838 5
7839};
7840
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007841static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07007842
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007843#ifdef MS_WINDOWS
7844#define HAVE_TIMES /* mandatory, for the method table */
7845#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007846
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007847#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007848
7849static PyObject *
7850build_times_result(double user, double system,
7851 double children_user, double children_system,
7852 double elapsed)
7853{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007854 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07007855 if (value == NULL)
7856 return NULL;
7857
7858#define SET(i, field) \
7859 { \
7860 PyObject *o = PyFloat_FromDouble(field); \
7861 if (!o) { \
7862 Py_DECREF(value); \
7863 return NULL; \
7864 } \
7865 PyStructSequence_SET_ITEM(value, i, o); \
7866 } \
7867
7868 SET(0, user);
7869 SET(1, system);
7870 SET(2, children_user);
7871 SET(3, children_system);
7872 SET(4, elapsed);
7873
7874#undef SET
7875
7876 return value;
7877}
7878
Larry Hastings605a62d2012-06-24 04:33:36 -07007879
Larry Hastings2f936352014-08-05 14:04:04 +10007880#ifndef MS_WINDOWS
7881#define NEED_TICKS_PER_SECOND
7882static long ticks_per_second = -1;
7883#endif /* MS_WINDOWS */
7884
7885/*[clinic input]
7886os.times
7887
7888Return a collection containing process timing information.
7889
7890The object returned behaves like a named tuple with these fields:
7891 (utime, stime, cutime, cstime, elapsed_time)
7892All fields are floating point numbers.
7893[clinic start generated code]*/
7894
Larry Hastings2f936352014-08-05 14:04:04 +10007895static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007896os_times_impl(PyObject *module)
7897/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007898#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007899{
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 FILETIME create, exit, kernel, user;
7901 HANDLE hProc;
7902 hProc = GetCurrentProcess();
7903 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7904 /* The fields of a FILETIME structure are the hi and lo part
7905 of a 64-bit value expressed in 100 nanosecond units.
7906 1e7 is one second in such units; 1e-7 the inverse.
7907 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7908 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007909 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 (double)(user.dwHighDateTime*429.4967296 +
7911 user.dwLowDateTime*1e-7),
7912 (double)(kernel.dwHighDateTime*429.4967296 +
7913 kernel.dwLowDateTime*1e-7),
7914 (double)0,
7915 (double)0,
7916 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007917}
Larry Hastings2f936352014-08-05 14:04:04 +10007918#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007919{
Larry Hastings2f936352014-08-05 14:04:04 +10007920
7921
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007922 struct tms t;
7923 clock_t c;
7924 errno = 0;
7925 c = times(&t);
7926 if (c == (clock_t) -1)
7927 return posix_error();
7928 return build_times_result(
7929 (double)t.tms_utime / ticks_per_second,
7930 (double)t.tms_stime / ticks_per_second,
7931 (double)t.tms_cutime / ticks_per_second,
7932 (double)t.tms_cstime / ticks_per_second,
7933 (double)c / ticks_per_second);
7934}
Larry Hastings2f936352014-08-05 14:04:04 +10007935#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007936#endif /* HAVE_TIMES */
7937
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007938
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007939#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007940/*[clinic input]
7941os.getsid
7942
7943 pid: pid_t
7944 /
7945
7946Call the system call getsid(pid) and return the result.
7947[clinic start generated code]*/
7948
Larry Hastings2f936352014-08-05 14:04:04 +10007949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007950os_getsid_impl(PyObject *module, pid_t pid)
7951/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007952{
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 sid = getsid(pid);
7955 if (sid < 0)
7956 return posix_error();
7957 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007958}
7959#endif /* HAVE_GETSID */
7960
7961
Guido van Rossumb6775db1994-08-01 11:34:53 +00007962#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007963/*[clinic input]
7964os.setsid
7965
7966Call the system call setsid().
7967[clinic start generated code]*/
7968
Larry Hastings2f936352014-08-05 14:04:04 +10007969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007970os_setsid_impl(PyObject *module)
7971/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007972{
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 if (setsid() < 0)
7974 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007975 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007976}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007977#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007978
Larry Hastings2f936352014-08-05 14:04:04 +10007979
Guido van Rossumb6775db1994-08-01 11:34:53 +00007980#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007981/*[clinic input]
7982os.setpgid
7983
7984 pid: pid_t
7985 pgrp: pid_t
7986 /
7987
7988Call the system call setpgid(pid, pgrp).
7989[clinic start generated code]*/
7990
Larry Hastings2f936352014-08-05 14:04:04 +10007991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007992os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7993/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007994{
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 if (setpgid(pid, pgrp) < 0)
7996 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007997 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007998}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007999#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008001
Guido van Rossumb6775db1994-08-01 11:34:53 +00008002#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008003/*[clinic input]
8004os.tcgetpgrp
8005
8006 fd: int
8007 /
8008
8009Return the process group associated with the terminal specified by fd.
8010[clinic start generated code]*/
8011
Larry Hastings2f936352014-08-05 14:04:04 +10008012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008013os_tcgetpgrp_impl(PyObject *module, int fd)
8014/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008015{
8016 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 if (pgid < 0)
8018 return posix_error();
8019 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008020}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008021#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008023
Guido van Rossumb6775db1994-08-01 11:34:53 +00008024#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008025/*[clinic input]
8026os.tcsetpgrp
8027
8028 fd: int
8029 pgid: pid_t
8030 /
8031
8032Set the process group associated with the terminal specified by fd.
8033[clinic start generated code]*/
8034
Larry Hastings2f936352014-08-05 14:04:04 +10008035static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008036os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8037/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008038{
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 if (tcsetpgrp(fd, pgid) < 0)
8040 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008041 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008042}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008043#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008044
Guido van Rossum687dd131993-05-17 08:34:16 +00008045/* Functions acting on file descriptors */
8046
Victor Stinnerdaf45552013-08-28 00:53:59 +02008047#ifdef O_CLOEXEC
8048extern int _Py_open_cloexec_works;
8049#endif
8050
Larry Hastings2f936352014-08-05 14:04:04 +10008051
8052/*[clinic input]
8053os.open -> int
8054 path: path_t
8055 flags: int
8056 mode: int = 0o777
8057 *
8058 dir_fd: dir_fd(requires='openat') = None
8059
8060# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8061
8062Open a file for low level IO. Returns a file descriptor (integer).
8063
8064If dir_fd is not None, it should be a file descriptor open to a directory,
8065 and path should be relative; path will then be relative to that directory.
8066dir_fd may not be implemented on your platform.
8067 If it is unavailable, using it will raise a NotImplementedError.
8068[clinic start generated code]*/
8069
Larry Hastings2f936352014-08-05 14:04:04 +10008070static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008071os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8072/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008073{
8074 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008075 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008076
Victor Stinnerdaf45552013-08-28 00:53:59 +02008077#ifdef O_CLOEXEC
8078 int *atomic_flag_works = &_Py_open_cloexec_works;
8079#elif !defined(MS_WINDOWS)
8080 int *atomic_flag_works = NULL;
8081#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008082
Victor Stinnerdaf45552013-08-28 00:53:59 +02008083#ifdef MS_WINDOWS
8084 flags |= O_NOINHERIT;
8085#elif defined(O_CLOEXEC)
8086 flags |= O_CLOEXEC;
8087#endif
8088
Steve Dower8fc89802015-04-12 00:26:27 -04008089 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008090 do {
8091 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008092#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008093 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008094#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008095#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008096 if (dir_fd != DEFAULT_DIR_FD)
8097 fd = openat(dir_fd, path->narrow, flags, mode);
8098 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008099#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008100 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008101#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008102 Py_END_ALLOW_THREADS
8103 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008104 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008105
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008106 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008107 if (!async_err)
8108 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008109 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008110 }
8111
Victor Stinnerdaf45552013-08-28 00:53:59 +02008112#ifndef MS_WINDOWS
8113 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8114 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008115 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008116 }
8117#endif
8118
Larry Hastings2f936352014-08-05 14:04:04 +10008119 return fd;
8120}
8121
8122
8123/*[clinic input]
8124os.close
8125
8126 fd: int
8127
8128Close a file descriptor.
8129[clinic start generated code]*/
8130
Barry Warsaw53699e91996-12-10 23:23:01 +00008131static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008132os_close_impl(PyObject *module, int fd)
8133/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008134{
Larry Hastings2f936352014-08-05 14:04:04 +10008135 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008136 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8137 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8138 * for more details.
8139 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008141 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008143 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 Py_END_ALLOW_THREADS
8145 if (res < 0)
8146 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008147 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008148}
8149
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008150
Larry Hastings2f936352014-08-05 14:04:04 +10008151/*[clinic input]
8152os.closerange
8153
8154 fd_low: int
8155 fd_high: int
8156 /
8157
8158Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8159[clinic start generated code]*/
8160
Larry Hastings2f936352014-08-05 14:04:04 +10008161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008162os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8163/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008164{
8165 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008167 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008168 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008169 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008170 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008171 Py_END_ALLOW_THREADS
8172 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008173}
8174
8175
Larry Hastings2f936352014-08-05 14:04:04 +10008176/*[clinic input]
8177os.dup -> int
8178
8179 fd: int
8180 /
8181
8182Return a duplicate of a file descriptor.
8183[clinic start generated code]*/
8184
Larry Hastings2f936352014-08-05 14:04:04 +10008185static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008186os_dup_impl(PyObject *module, int fd)
8187/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008188{
8189 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008190}
8191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008192
Larry Hastings2f936352014-08-05 14:04:04 +10008193/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008194os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008195 fd: int
8196 fd2: int
8197 inheritable: bool=True
8198
8199Duplicate file descriptor.
8200[clinic start generated code]*/
8201
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008202static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008203os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008204/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008205{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008206 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008207#if defined(HAVE_DUP3) && \
8208 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8209 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008210 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008211#endif
8212
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008213 if (fd < 0 || fd2 < 0) {
8214 posix_error();
8215 return -1;
8216 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008217
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008218 /* dup2() can fail with EINTR if the target FD is already open, because it
8219 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8220 * upon close(), and therefore below.
8221 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008222#ifdef MS_WINDOWS
8223 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008224 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008225 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008226 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008227 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008228 if (res < 0) {
8229 posix_error();
8230 return -1;
8231 }
8232 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008233
8234 /* Character files like console cannot be make non-inheritable */
8235 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8236 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008237 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008238 }
8239
8240#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8241 Py_BEGIN_ALLOW_THREADS
8242 if (!inheritable)
8243 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8244 else
8245 res = dup2(fd, fd2);
8246 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008247 if (res < 0) {
8248 posix_error();
8249 return -1;
8250 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008251
8252#else
8253
8254#ifdef HAVE_DUP3
8255 if (!inheritable && dup3_works != 0) {
8256 Py_BEGIN_ALLOW_THREADS
8257 res = dup3(fd, fd2, O_CLOEXEC);
8258 Py_END_ALLOW_THREADS
8259 if (res < 0) {
8260 if (dup3_works == -1)
8261 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008262 if (dup3_works) {
8263 posix_error();
8264 return -1;
8265 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008266 }
8267 }
8268
8269 if (inheritable || dup3_works == 0)
8270 {
8271#endif
8272 Py_BEGIN_ALLOW_THREADS
8273 res = dup2(fd, fd2);
8274 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008275 if (res < 0) {
8276 posix_error();
8277 return -1;
8278 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008279
8280 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8281 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008282 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008283 }
8284#ifdef HAVE_DUP3
8285 }
8286#endif
8287
8288#endif
8289
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008290 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008291}
8292
Larry Hastings2f936352014-08-05 14:04:04 +10008293
Ross Lagerwall7807c352011-03-17 20:20:30 +02008294#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008295/*[clinic input]
8296os.lockf
8297
8298 fd: int
8299 An open file descriptor.
8300 command: int
8301 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8302 length: Py_off_t
8303 The number of bytes to lock, starting at the current position.
8304 /
8305
8306Apply, test or remove a POSIX lock on an open file descriptor.
8307
8308[clinic start generated code]*/
8309
Larry Hastings2f936352014-08-05 14:04:04 +10008310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008311os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8312/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008313{
8314 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008315
8316 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008317 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008318 Py_END_ALLOW_THREADS
8319
8320 if (res < 0)
8321 return posix_error();
8322
8323 Py_RETURN_NONE;
8324}
Larry Hastings2f936352014-08-05 14:04:04 +10008325#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008327
Larry Hastings2f936352014-08-05 14:04:04 +10008328/*[clinic input]
8329os.lseek -> Py_off_t
8330
8331 fd: int
8332 position: Py_off_t
8333 how: int
8334 /
8335
8336Set the position of a file descriptor. Return the new position.
8337
8338Return the new cursor position in number of bytes
8339relative to the beginning of the file.
8340[clinic start generated code]*/
8341
Larry Hastings2f936352014-08-05 14:04:04 +10008342static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008343os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8344/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008345{
8346 Py_off_t result;
8347
Guido van Rossum687dd131993-05-17 08:34:16 +00008348#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8350 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008351 case 0: how = SEEK_SET; break;
8352 case 1: how = SEEK_CUR; break;
8353 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008354 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008355#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008356
Victor Stinner8c62be82010-05-06 00:08:46 +00008357 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008358 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008359#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008360 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008361#else
Larry Hastings2f936352014-08-05 14:04:04 +10008362 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008363#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008364 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008366 if (result < 0)
8367 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008368
Larry Hastings2f936352014-08-05 14:04:04 +10008369 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008370}
8371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008372
Larry Hastings2f936352014-08-05 14:04:04 +10008373/*[clinic input]
8374os.read
8375 fd: int
8376 length: Py_ssize_t
8377 /
8378
8379Read from a file descriptor. Returns a bytes object.
8380[clinic start generated code]*/
8381
Larry Hastings2f936352014-08-05 14:04:04 +10008382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008383os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8384/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008385{
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 Py_ssize_t n;
8387 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008388
8389 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 errno = EINVAL;
8391 return posix_error();
8392 }
Larry Hastings2f936352014-08-05 14:04:04 +10008393
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008394 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008395
8396 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 if (buffer == NULL)
8398 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008399
Victor Stinner66aab0c2015-03-19 22:53:20 +01008400 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8401 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008403 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 }
Larry Hastings2f936352014-08-05 14:04:04 +10008405
8406 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008408
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008410}
8411
Ross Lagerwall7807c352011-03-17 20:20:30 +02008412#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008413 || defined(__APPLE__))) \
8414 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8415 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8416static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008417iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008418{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008419 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008420
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008421 *iov = PyMem_New(struct iovec, cnt);
8422 if (*iov == NULL) {
8423 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008424 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008425 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008426
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008427 *buf = PyMem_New(Py_buffer, cnt);
8428 if (*buf == NULL) {
8429 PyMem_Del(*iov);
8430 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008431 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008432 }
8433
8434 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008435 PyObject *item = PySequence_GetItem(seq, i);
8436 if (item == NULL)
8437 goto fail;
8438 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8439 Py_DECREF(item);
8440 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008441 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008442 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008443 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008444 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008445 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008446 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008447
8448fail:
8449 PyMem_Del(*iov);
8450 for (j = 0; j < i; j++) {
8451 PyBuffer_Release(&(*buf)[j]);
8452 }
8453 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008454 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008455}
8456
8457static void
8458iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8459{
8460 int i;
8461 PyMem_Del(iov);
8462 for (i = 0; i < cnt; i++) {
8463 PyBuffer_Release(&buf[i]);
8464 }
8465 PyMem_Del(buf);
8466}
8467#endif
8468
Larry Hastings2f936352014-08-05 14:04:04 +10008469
Ross Lagerwall7807c352011-03-17 20:20:30 +02008470#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008471/*[clinic input]
8472os.readv -> Py_ssize_t
8473
8474 fd: int
8475 buffers: object
8476 /
8477
8478Read from a file descriptor fd into an iterable of buffers.
8479
8480The buffers should be mutable buffers accepting bytes.
8481readv will transfer data into each buffer until it is full
8482and then move on to the next buffer in the sequence to hold
8483the rest of the data.
8484
8485readv returns the total number of bytes read,
8486which may be less than the total capacity of all the buffers.
8487[clinic start generated code]*/
8488
Larry Hastings2f936352014-08-05 14:04:04 +10008489static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008490os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8491/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008492{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008493 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008494 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008495 struct iovec *iov;
8496 Py_buffer *buf;
8497
Larry Hastings2f936352014-08-05 14:04:04 +10008498 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008499 PyErr_SetString(PyExc_TypeError,
8500 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008501 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008502 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008503
Larry Hastings2f936352014-08-05 14:04:04 +10008504 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008505 if (cnt < 0)
8506 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008507
8508 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8509 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008510
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008511 do {
8512 Py_BEGIN_ALLOW_THREADS
8513 n = readv(fd, iov, cnt);
8514 Py_END_ALLOW_THREADS
8515 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008516
8517 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008518 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008519 if (!async_err)
8520 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008521 return -1;
8522 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008523
Larry Hastings2f936352014-08-05 14:04:04 +10008524 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008525}
Larry Hastings2f936352014-08-05 14:04:04 +10008526#endif /* HAVE_READV */
8527
Ross Lagerwall7807c352011-03-17 20:20:30 +02008528
8529#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008530/*[clinic input]
8531# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8532os.pread
8533
8534 fd: int
8535 length: int
8536 offset: Py_off_t
8537 /
8538
8539Read a number of bytes from a file descriptor starting at a particular offset.
8540
8541Read length bytes from file descriptor fd, starting at offset bytes from
8542the beginning of the file. The file offset remains unchanged.
8543[clinic start generated code]*/
8544
Larry Hastings2f936352014-08-05 14:04:04 +10008545static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008546os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8547/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008548{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008549 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008550 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008551 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008552
Larry Hastings2f936352014-08-05 14:04:04 +10008553 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008554 errno = EINVAL;
8555 return posix_error();
8556 }
Larry Hastings2f936352014-08-05 14:04:04 +10008557 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008558 if (buffer == NULL)
8559 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008560
8561 do {
8562 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008563 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008564 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008565 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008566 Py_END_ALLOW_THREADS
8567 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8568
Ross Lagerwall7807c352011-03-17 20:20:30 +02008569 if (n < 0) {
8570 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008571 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008572 }
Larry Hastings2f936352014-08-05 14:04:04 +10008573 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008574 _PyBytes_Resize(&buffer, n);
8575 return buffer;
8576}
Larry Hastings2f936352014-08-05 14:04:04 +10008577#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008578
Pablo Galindo4defba32018-01-27 16:16:37 +00008579#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8580/*[clinic input]
8581os.preadv -> Py_ssize_t
8582
8583 fd: int
8584 buffers: object
8585 offset: Py_off_t
8586 flags: int = 0
8587 /
8588
8589Reads from a file descriptor into a number of mutable bytes-like objects.
8590
8591Combines the functionality of readv() and pread(). As readv(), it will
8592transfer data into each buffer until it is full and then move on to the next
8593buffer in the sequence to hold the rest of the data. Its fourth argument,
8594specifies the file offset at which the input operation is to be performed. It
8595will return the total number of bytes read (which can be less than the total
8596capacity of all the objects).
8597
8598The flags argument contains a bitwise OR of zero or more of the following flags:
8599
8600- RWF_HIPRI
8601- RWF_NOWAIT
8602
8603Using non-zero flags requires Linux 4.6 or newer.
8604[clinic start generated code]*/
8605
8606static Py_ssize_t
8607os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8608 int flags)
8609/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8610{
8611 Py_ssize_t cnt, n;
8612 int async_err = 0;
8613 struct iovec *iov;
8614 Py_buffer *buf;
8615
8616 if (!PySequence_Check(buffers)) {
8617 PyErr_SetString(PyExc_TypeError,
8618 "preadv2() arg 2 must be a sequence");
8619 return -1;
8620 }
8621
8622 cnt = PySequence_Size(buffers);
8623 if (cnt < 0) {
8624 return -1;
8625 }
8626
8627#ifndef HAVE_PREADV2
8628 if(flags != 0) {
8629 argument_unavailable_error("preadv2", "flags");
8630 return -1;
8631 }
8632#endif
8633
8634 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8635 return -1;
8636 }
8637#ifdef HAVE_PREADV2
8638 do {
8639 Py_BEGIN_ALLOW_THREADS
8640 _Py_BEGIN_SUPPRESS_IPH
8641 n = preadv2(fd, iov, cnt, offset, flags);
8642 _Py_END_SUPPRESS_IPH
8643 Py_END_ALLOW_THREADS
8644 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8645#else
8646 do {
8647 Py_BEGIN_ALLOW_THREADS
8648 _Py_BEGIN_SUPPRESS_IPH
8649 n = preadv(fd, iov, cnt, offset);
8650 _Py_END_SUPPRESS_IPH
8651 Py_END_ALLOW_THREADS
8652 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8653#endif
8654
8655 iov_cleanup(iov, buf, cnt);
8656 if (n < 0) {
8657 if (!async_err) {
8658 posix_error();
8659 }
8660 return -1;
8661 }
8662
8663 return n;
8664}
8665#endif /* HAVE_PREADV */
8666
Larry Hastings2f936352014-08-05 14:04:04 +10008667
8668/*[clinic input]
8669os.write -> Py_ssize_t
8670
8671 fd: int
8672 data: Py_buffer
8673 /
8674
8675Write a bytes object to a file descriptor.
8676[clinic start generated code]*/
8677
Larry Hastings2f936352014-08-05 14:04:04 +10008678static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008679os_write_impl(PyObject *module, int fd, Py_buffer *data)
8680/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008681{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008682 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683}
8684
8685#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008686PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008687"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008688sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008689 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008690Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008691
Larry Hastings2f936352014-08-05 14:04:04 +10008692/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008693static PyObject *
8694posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8695{
8696 int in, out;
8697 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008698 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008699 off_t offset;
8700
8701#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8702#ifndef __APPLE__
8703 Py_ssize_t len;
8704#endif
8705 PyObject *headers = NULL, *trailers = NULL;
8706 Py_buffer *hbuf, *tbuf;
8707 off_t sbytes;
8708 struct sf_hdtr sf;
8709 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008710 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008711 static char *keywords[] = {"out", "in",
8712 "offset", "count",
8713 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008714
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008715 sf.headers = NULL;
8716 sf.trailers = NULL;
8717
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008718#ifdef __APPLE__
8719 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008720 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008721#else
8722 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008723 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008724#endif
8725 &headers, &trailers, &flags))
8726 return NULL;
8727 if (headers != NULL) {
8728 if (!PySequence_Check(headers)) {
8729 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008730 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008731 return NULL;
8732 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008733 Py_ssize_t i = PySequence_Size(headers);
8734 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008735 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008736 if (i > INT_MAX) {
8737 PyErr_SetString(PyExc_OverflowError,
8738 "sendfile() header is too large");
8739 return NULL;
8740 }
8741 if (i > 0) {
8742 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008743 if (iov_setup(&(sf.headers), &hbuf,
8744 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008745 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008746#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008747 for (i = 0; i < sf.hdr_cnt; i++) {
8748 Py_ssize_t blen = sf.headers[i].iov_len;
8749# define OFF_T_MAX 0x7fffffffffffffff
8750 if (sbytes >= OFF_T_MAX - blen) {
8751 PyErr_SetString(PyExc_OverflowError,
8752 "sendfile() header is too large");
8753 return NULL;
8754 }
8755 sbytes += blen;
8756 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008757#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008758 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008759 }
8760 }
8761 if (trailers != NULL) {
8762 if (!PySequence_Check(trailers)) {
8763 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008764 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008765 return NULL;
8766 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008767 Py_ssize_t i = PySequence_Size(trailers);
8768 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008769 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008770 if (i > INT_MAX) {
8771 PyErr_SetString(PyExc_OverflowError,
8772 "sendfile() trailer is too large");
8773 return NULL;
8774 }
8775 if (i > 0) {
8776 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008777 if (iov_setup(&(sf.trailers), &tbuf,
8778 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008779 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008780 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008781 }
8782 }
8783
Steve Dower8fc89802015-04-12 00:26:27 -04008784 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008785 do {
8786 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008787#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008788 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008789#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008790 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008791#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008792 Py_END_ALLOW_THREADS
8793 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008794 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008795
8796 if (sf.headers != NULL)
8797 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8798 if (sf.trailers != NULL)
8799 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8800
8801 if (ret < 0) {
8802 if ((errno == EAGAIN) || (errno == EBUSY)) {
8803 if (sbytes != 0) {
8804 // some data has been sent
8805 goto done;
8806 }
8807 else {
8808 // no data has been sent; upper application is supposed
8809 // to retry on EAGAIN or EBUSY
8810 return posix_error();
8811 }
8812 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008813 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008814 }
8815 goto done;
8816
8817done:
8818 #if !defined(HAVE_LARGEFILE_SUPPORT)
8819 return Py_BuildValue("l", sbytes);
8820 #else
8821 return Py_BuildValue("L", sbytes);
8822 #endif
8823
8824#else
8825 Py_ssize_t count;
8826 PyObject *offobj;
8827 static char *keywords[] = {"out", "in",
8828 "offset", "count", NULL};
8829 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8830 keywords, &out, &in, &offobj, &count))
8831 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008832#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008833 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008834 do {
8835 Py_BEGIN_ALLOW_THREADS
8836 ret = sendfile(out, in, NULL, count);
8837 Py_END_ALLOW_THREADS
8838 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008839 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008840 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008841 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008842 }
8843#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008844 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008845 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008846
8847 do {
8848 Py_BEGIN_ALLOW_THREADS
8849 ret = sendfile(out, in, &offset, count);
8850 Py_END_ALLOW_THREADS
8851 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008852 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008853 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008854 return Py_BuildValue("n", ret);
8855#endif
8856}
Larry Hastings2f936352014-08-05 14:04:04 +10008857#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008858
Larry Hastings2f936352014-08-05 14:04:04 +10008859
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008860#if defined(__APPLE__)
8861/*[clinic input]
8862os._fcopyfile
8863
8864 infd: int
8865 outfd: int
8866 flags: int
8867 /
8868
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008869Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008870[clinic start generated code]*/
8871
8872static PyObject *
8873os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008874/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008875{
8876 int ret;
8877
8878 Py_BEGIN_ALLOW_THREADS
8879 ret = fcopyfile(infd, outfd, NULL, flags);
8880 Py_END_ALLOW_THREADS
8881 if (ret < 0)
8882 return posix_error();
8883 Py_RETURN_NONE;
8884}
8885#endif
8886
8887
Larry Hastings2f936352014-08-05 14:04:04 +10008888/*[clinic input]
8889os.fstat
8890
8891 fd : int
8892
8893Perform a stat system call on the given file descriptor.
8894
8895Like stat(), but for an open file descriptor.
8896Equivalent to os.stat(fd).
8897[clinic start generated code]*/
8898
Larry Hastings2f936352014-08-05 14:04:04 +10008899static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008900os_fstat_impl(PyObject *module, int fd)
8901/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008902{
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 STRUCT_STAT st;
8904 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008905 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008906
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008907 do {
8908 Py_BEGIN_ALLOW_THREADS
8909 res = FSTAT(fd, &st);
8910 Py_END_ALLOW_THREADS
8911 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008913#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008914 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008915#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008916 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008917#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 }
Tim Peters5aa91602002-01-30 05:46:57 +00008919
Victor Stinner4195b5c2012-02-08 23:03:19 +01008920 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008921}
8922
Larry Hastings2f936352014-08-05 14:04:04 +10008923
8924/*[clinic input]
8925os.isatty -> bool
8926 fd: int
8927 /
8928
8929Return True if the fd is connected to a terminal.
8930
8931Return True if the file descriptor is an open file descriptor
8932connected to the slave end of a terminal.
8933[clinic start generated code]*/
8934
Larry Hastings2f936352014-08-05 14:04:04 +10008935static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008936os_isatty_impl(PyObject *module, int fd)
8937/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008938{
Steve Dower8fc89802015-04-12 00:26:27 -04008939 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008940 _Py_BEGIN_SUPPRESS_IPH
8941 return_value = isatty(fd);
8942 _Py_END_SUPPRESS_IPH
8943 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008944}
8945
8946
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008947#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008948/*[clinic input]
8949os.pipe
8950
8951Create a pipe.
8952
8953Returns a tuple of two file descriptors:
8954 (read_fd, write_fd)
8955[clinic start generated code]*/
8956
Larry Hastings2f936352014-08-05 14:04:04 +10008957static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008958os_pipe_impl(PyObject *module)
8959/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008960{
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008962#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008964 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008966#else
8967 int res;
8968#endif
8969
8970#ifdef MS_WINDOWS
8971 attr.nLength = sizeof(attr);
8972 attr.lpSecurityDescriptor = NULL;
8973 attr.bInheritHandle = FALSE;
8974
8975 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008976 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008977 ok = CreatePipe(&read, &write, &attr, 0);
8978 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008979 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8980 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008981 if (fds[0] == -1 || fds[1] == -1) {
8982 CloseHandle(read);
8983 CloseHandle(write);
8984 ok = 0;
8985 }
8986 }
Steve Dowerc3630612016-11-19 18:41:16 -08008987 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008988 Py_END_ALLOW_THREADS
8989
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008991 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008992#else
8993
8994#ifdef HAVE_PIPE2
8995 Py_BEGIN_ALLOW_THREADS
8996 res = pipe2(fds, O_CLOEXEC);
8997 Py_END_ALLOW_THREADS
8998
8999 if (res != 0 && errno == ENOSYS)
9000 {
9001#endif
9002 Py_BEGIN_ALLOW_THREADS
9003 res = pipe(fds);
9004 Py_END_ALLOW_THREADS
9005
9006 if (res == 0) {
9007 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9008 close(fds[0]);
9009 close(fds[1]);
9010 return NULL;
9011 }
9012 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9013 close(fds[0]);
9014 close(fds[1]);
9015 return NULL;
9016 }
9017 }
9018#ifdef HAVE_PIPE2
9019 }
9020#endif
9021
9022 if (res != 0)
9023 return PyErr_SetFromErrno(PyExc_OSError);
9024#endif /* !MS_WINDOWS */
9025 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009026}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009027#endif /* HAVE_PIPE */
9028
Larry Hastings2f936352014-08-05 14:04:04 +10009029
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009030#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009031/*[clinic input]
9032os.pipe2
9033
9034 flags: int
9035 /
9036
9037Create a pipe with flags set atomically.
9038
9039Returns a tuple of two file descriptors:
9040 (read_fd, write_fd)
9041
9042flags can be constructed by ORing together one or more of these values:
9043O_NONBLOCK, O_CLOEXEC.
9044[clinic start generated code]*/
9045
Larry Hastings2f936352014-08-05 14:04:04 +10009046static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009047os_pipe2_impl(PyObject *module, int flags)
9048/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009049{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009050 int fds[2];
9051 int res;
9052
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009053 res = pipe2(fds, flags);
9054 if (res != 0)
9055 return posix_error();
9056 return Py_BuildValue("(ii)", fds[0], fds[1]);
9057}
9058#endif /* HAVE_PIPE2 */
9059
Larry Hastings2f936352014-08-05 14:04:04 +10009060
Ross Lagerwall7807c352011-03-17 20:20:30 +02009061#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009062/*[clinic input]
9063os.writev -> Py_ssize_t
9064 fd: int
9065 buffers: object
9066 /
9067
9068Iterate over buffers, and write the contents of each to a file descriptor.
9069
9070Returns the total number of bytes written.
9071buffers must be a sequence of bytes-like objects.
9072[clinic start generated code]*/
9073
Larry Hastings2f936352014-08-05 14:04:04 +10009074static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009075os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9076/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009077{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009078 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009079 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009080 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009081 struct iovec *iov;
9082 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009083
9084 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009085 PyErr_SetString(PyExc_TypeError,
9086 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009087 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009088 }
Larry Hastings2f936352014-08-05 14:04:04 +10009089 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009090 if (cnt < 0)
9091 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009092
Larry Hastings2f936352014-08-05 14:04:04 +10009093 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9094 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009095 }
9096
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009097 do {
9098 Py_BEGIN_ALLOW_THREADS
9099 result = writev(fd, iov, cnt);
9100 Py_END_ALLOW_THREADS
9101 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009102
9103 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009104 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009105 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009106
Georg Brandl306336b2012-06-24 12:55:33 +02009107 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009108}
Larry Hastings2f936352014-08-05 14:04:04 +10009109#endif /* HAVE_WRITEV */
9110
9111
9112#ifdef HAVE_PWRITE
9113/*[clinic input]
9114os.pwrite -> Py_ssize_t
9115
9116 fd: int
9117 buffer: Py_buffer
9118 offset: Py_off_t
9119 /
9120
9121Write bytes to a file descriptor starting at a particular offset.
9122
9123Write buffer to fd, starting at offset bytes from the beginning of
9124the file. Returns the number of bytes writte. Does not change the
9125current file offset.
9126[clinic start generated code]*/
9127
Larry Hastings2f936352014-08-05 14:04:04 +10009128static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009129os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9130/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009131{
9132 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009133 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009134
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009135 do {
9136 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009137 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009138 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009139 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009140 Py_END_ALLOW_THREADS
9141 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009142
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009143 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009144 posix_error();
9145 return size;
9146}
9147#endif /* HAVE_PWRITE */
9148
Pablo Galindo4defba32018-01-27 16:16:37 +00009149#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9150/*[clinic input]
9151os.pwritev -> Py_ssize_t
9152
9153 fd: int
9154 buffers: object
9155 offset: Py_off_t
9156 flags: int = 0
9157 /
9158
9159Writes the contents of bytes-like objects to a file descriptor at a given offset.
9160
9161Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9162of bytes-like objects. Buffers are processed in array order. Entire contents of first
9163buffer is written before proceeding to second, and so on. The operating system may
9164set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9165This function writes the contents of each object to the file descriptor and returns
9166the total number of bytes written.
9167
9168The flags argument contains a bitwise OR of zero or more of the following flags:
9169
9170- RWF_DSYNC
9171- RWF_SYNC
9172
9173Using non-zero flags requires Linux 4.7 or newer.
9174[clinic start generated code]*/
9175
9176static Py_ssize_t
9177os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9178 int flags)
9179/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9180{
9181 Py_ssize_t cnt;
9182 Py_ssize_t result;
9183 int async_err = 0;
9184 struct iovec *iov;
9185 Py_buffer *buf;
9186
9187 if (!PySequence_Check(buffers)) {
9188 PyErr_SetString(PyExc_TypeError,
9189 "pwritev() arg 2 must be a sequence");
9190 return -1;
9191 }
9192
9193 cnt = PySequence_Size(buffers);
9194 if (cnt < 0) {
9195 return -1;
9196 }
9197
9198#ifndef HAVE_PWRITEV2
9199 if(flags != 0) {
9200 argument_unavailable_error("pwritev2", "flags");
9201 return -1;
9202 }
9203#endif
9204
9205 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9206 return -1;
9207 }
9208#ifdef HAVE_PWRITEV2
9209 do {
9210 Py_BEGIN_ALLOW_THREADS
9211 _Py_BEGIN_SUPPRESS_IPH
9212 result = pwritev2(fd, iov, cnt, offset, flags);
9213 _Py_END_SUPPRESS_IPH
9214 Py_END_ALLOW_THREADS
9215 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9216#else
9217 do {
9218 Py_BEGIN_ALLOW_THREADS
9219 _Py_BEGIN_SUPPRESS_IPH
9220 result = pwritev(fd, iov, cnt, offset);
9221 _Py_END_SUPPRESS_IPH
9222 Py_END_ALLOW_THREADS
9223 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9224#endif
9225
9226 iov_cleanup(iov, buf, cnt);
9227 if (result < 0) {
9228 if (!async_err) {
9229 posix_error();
9230 }
9231 return -1;
9232 }
9233
9234 return result;
9235}
9236#endif /* HAVE_PWRITEV */
9237
9238
9239
Larry Hastings2f936352014-08-05 14:04:04 +10009240
9241#ifdef HAVE_MKFIFO
9242/*[clinic input]
9243os.mkfifo
9244
9245 path: path_t
9246 mode: int=0o666
9247 *
9248 dir_fd: dir_fd(requires='mkfifoat')=None
9249
9250Create a "fifo" (a POSIX named pipe).
9251
9252If dir_fd is not None, it should be a file descriptor open to a directory,
9253 and path should be relative; path will then be relative to that directory.
9254dir_fd may not be implemented on your platform.
9255 If it is unavailable, using it will raise a NotImplementedError.
9256[clinic start generated code]*/
9257
Larry Hastings2f936352014-08-05 14:04:04 +10009258static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009259os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9260/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009261{
9262 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009263 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009264
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009265 do {
9266 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009267#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009268 if (dir_fd != DEFAULT_DIR_FD)
9269 result = mkfifoat(dir_fd, path->narrow, mode);
9270 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009271#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009272 result = mkfifo(path->narrow, mode);
9273 Py_END_ALLOW_THREADS
9274 } while (result != 0 && errno == EINTR &&
9275 !(async_err = PyErr_CheckSignals()));
9276 if (result != 0)
9277 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009278
9279 Py_RETURN_NONE;
9280}
9281#endif /* HAVE_MKFIFO */
9282
9283
9284#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9285/*[clinic input]
9286os.mknod
9287
9288 path: path_t
9289 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009290 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009291 *
9292 dir_fd: dir_fd(requires='mknodat')=None
9293
9294Create a node in the file system.
9295
9296Create a node in the file system (file, device special file or named pipe)
9297at path. mode specifies both the permissions to use and the
9298type of node to be created, being combined (bitwise OR) with one of
9299S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9300device defines the newly created device special file (probably using
9301os.makedev()). Otherwise device is ignored.
9302
9303If dir_fd is not None, it should be a file descriptor open to a directory,
9304 and path should be relative; path will then be relative to that directory.
9305dir_fd may not be implemented on your platform.
9306 If it is unavailable, using it will raise a NotImplementedError.
9307[clinic start generated code]*/
9308
Larry Hastings2f936352014-08-05 14:04:04 +10009309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009310os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009311 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009312/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009313{
9314 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009315 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009316
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009317 do {
9318 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009319#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009320 if (dir_fd != DEFAULT_DIR_FD)
9321 result = mknodat(dir_fd, path->narrow, mode, device);
9322 else
Larry Hastings2f936352014-08-05 14:04:04 +10009323#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009324 result = mknod(path->narrow, mode, device);
9325 Py_END_ALLOW_THREADS
9326 } while (result != 0 && errno == EINTR &&
9327 !(async_err = PyErr_CheckSignals()));
9328 if (result != 0)
9329 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009330
9331 Py_RETURN_NONE;
9332}
9333#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9334
9335
9336#ifdef HAVE_DEVICE_MACROS
9337/*[clinic input]
9338os.major -> unsigned_int
9339
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009340 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009341 /
9342
9343Extracts a device major number from a raw device number.
9344[clinic start generated code]*/
9345
Larry Hastings2f936352014-08-05 14:04:04 +10009346static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009347os_major_impl(PyObject *module, dev_t device)
9348/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009349{
9350 return major(device);
9351}
9352
9353
9354/*[clinic input]
9355os.minor -> unsigned_int
9356
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009357 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009358 /
9359
9360Extracts a device minor number from a raw device number.
9361[clinic start generated code]*/
9362
Larry Hastings2f936352014-08-05 14:04:04 +10009363static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009364os_minor_impl(PyObject *module, dev_t device)
9365/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009366{
9367 return minor(device);
9368}
9369
9370
9371/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009372os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009373
9374 major: int
9375 minor: int
9376 /
9377
9378Composes a raw device number from the major and minor device numbers.
9379[clinic start generated code]*/
9380
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009381static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009382os_makedev_impl(PyObject *module, int major, int minor)
9383/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009384{
9385 return makedev(major, minor);
9386}
9387#endif /* HAVE_DEVICE_MACROS */
9388
9389
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009390#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009391/*[clinic input]
9392os.ftruncate
9393
9394 fd: int
9395 length: Py_off_t
9396 /
9397
9398Truncate a file, specified by file descriptor, to a specific length.
9399[clinic start generated code]*/
9400
Larry Hastings2f936352014-08-05 14:04:04 +10009401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009402os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9403/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009404{
9405 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009406 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009407
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009408 do {
9409 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009410 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009411#ifdef MS_WINDOWS
9412 result = _chsize_s(fd, length);
9413#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009414 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009415#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009416 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009417 Py_END_ALLOW_THREADS
9418 } while (result != 0 && errno == EINTR &&
9419 !(async_err = PyErr_CheckSignals()));
9420 if (result != 0)
9421 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009422 Py_RETURN_NONE;
9423}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009424#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009425
9426
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009427#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009428/*[clinic input]
9429os.truncate
9430 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9431 length: Py_off_t
9432
9433Truncate a file, specified by path, to a specific length.
9434
9435On some platforms, path may also be specified as an open file descriptor.
9436 If this functionality is unavailable, using it raises an exception.
9437[clinic start generated code]*/
9438
Larry Hastings2f936352014-08-05 14:04:04 +10009439static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009440os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9441/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009442{
9443 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009444#ifdef MS_WINDOWS
9445 int fd;
9446#endif
9447
9448 if (path->fd != -1)
9449 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009450
9451 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009452 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009453#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009454 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009455 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009456 result = -1;
9457 else {
9458 result = _chsize_s(fd, length);
9459 close(fd);
9460 if (result < 0)
9461 errno = result;
9462 }
9463#else
9464 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009465#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009466 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009467 Py_END_ALLOW_THREADS
9468 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009469 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009470
9471 Py_RETURN_NONE;
9472}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009473#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009474
Ross Lagerwall7807c352011-03-17 20:20:30 +02009475
Victor Stinnerd6b17692014-09-30 12:20:05 +02009476/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9477 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9478 defined, which is the case in Python on AIX. AIX bug report:
9479 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9480#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9481# define POSIX_FADVISE_AIX_BUG
9482#endif
9483
Victor Stinnerec39e262014-09-30 12:35:58 +02009484
Victor Stinnerd6b17692014-09-30 12:20:05 +02009485#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009486/*[clinic input]
9487os.posix_fallocate
9488
9489 fd: int
9490 offset: Py_off_t
9491 length: Py_off_t
9492 /
9493
9494Ensure a file has allocated at least a particular number of bytes on disk.
9495
9496Ensure that the file specified by fd encompasses a range of bytes
9497starting at offset bytes from the beginning and continuing for length bytes.
9498[clinic start generated code]*/
9499
Larry Hastings2f936352014-08-05 14:04:04 +10009500static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009501os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009502 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009503/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009504{
9505 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009506 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009507
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009508 do {
9509 Py_BEGIN_ALLOW_THREADS
9510 result = posix_fallocate(fd, offset, length);
9511 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009512 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9513
9514 if (result == 0)
9515 Py_RETURN_NONE;
9516
9517 if (async_err)
9518 return NULL;
9519
9520 errno = result;
9521 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009522}
Victor Stinnerec39e262014-09-30 12:35:58 +02009523#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009524
Ross Lagerwall7807c352011-03-17 20:20:30 +02009525
Victor Stinnerd6b17692014-09-30 12:20:05 +02009526#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009527/*[clinic input]
9528os.posix_fadvise
9529
9530 fd: int
9531 offset: Py_off_t
9532 length: Py_off_t
9533 advice: int
9534 /
9535
9536Announce an intention to access data in a specific pattern.
9537
9538Announce an intention to access data in a specific pattern, thus allowing
9539the kernel to make optimizations.
9540The advice applies to the region of the file specified by fd starting at
9541offset and continuing for length bytes.
9542advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9543POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9544POSIX_FADV_DONTNEED.
9545[clinic start generated code]*/
9546
Larry Hastings2f936352014-08-05 14:04:04 +10009547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009548os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009549 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009550/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009551{
9552 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009553 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009554
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009555 do {
9556 Py_BEGIN_ALLOW_THREADS
9557 result = posix_fadvise(fd, offset, length, advice);
9558 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009559 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9560
9561 if (result == 0)
9562 Py_RETURN_NONE;
9563
9564 if (async_err)
9565 return NULL;
9566
9567 errno = result;
9568 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009569}
Victor Stinnerec39e262014-09-30 12:35:58 +02009570#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009571
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009572#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009573
Fred Drake762e2061999-08-26 17:23:54 +00009574/* Save putenv() parameters as values here, so we can collect them when they
9575 * get re-set with another call for the same key. */
9576static PyObject *posix_putenv_garbage;
9577
Larry Hastings2f936352014-08-05 14:04:04 +10009578static void
9579posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009580{
Larry Hastings2f936352014-08-05 14:04:04 +10009581 /* Install the first arg and newstr in posix_putenv_garbage;
9582 * this will cause previous value to be collected. This has to
9583 * happen after the real putenv() call because the old value
9584 * was still accessible until then. */
9585 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9586 /* really not much we can do; just leak */
9587 PyErr_Clear();
9588 else
9589 Py_DECREF(value);
9590}
9591
9592
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009593#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009594/*[clinic input]
9595os.putenv
9596
9597 name: unicode
9598 value: unicode
9599 /
9600
9601Change or add an environment variable.
9602[clinic start generated code]*/
9603
Larry Hastings2f936352014-08-05 14:04:04 +10009604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009605os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9606/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009607{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009608 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009609 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009610
Serhiy Storchaka77703942017-06-25 07:33:01 +03009611 /* Search from index 1 because on Windows starting '=' is allowed for
9612 defining hidden environment variables. */
9613 if (PyUnicode_GET_LENGTH(name) == 0 ||
9614 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9615 {
9616 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9617 return NULL;
9618 }
Larry Hastings2f936352014-08-05 14:04:04 +10009619 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9620 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009621 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009622 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009623
9624 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9625 if (env == NULL)
9626 goto error;
9627 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009628 PyErr_Format(PyExc_ValueError,
9629 "the environment variable is longer than %u characters",
9630 _MAX_ENV);
9631 goto error;
9632 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009633 if (wcslen(env) != (size_t)size) {
9634 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009635 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009636 }
9637
Larry Hastings2f936352014-08-05 14:04:04 +10009638 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009640 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009642
Larry Hastings2f936352014-08-05 14:04:04 +10009643 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009644 Py_RETURN_NONE;
9645
9646error:
Larry Hastings2f936352014-08-05 14:04:04 +10009647 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009648 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009649}
Larry Hastings2f936352014-08-05 14:04:04 +10009650#else /* MS_WINDOWS */
9651/*[clinic input]
9652os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009653
Larry Hastings2f936352014-08-05 14:04:04 +10009654 name: FSConverter
9655 value: FSConverter
9656 /
9657
9658Change or add an environment variable.
9659[clinic start generated code]*/
9660
Larry Hastings2f936352014-08-05 14:04:04 +10009661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009662os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9663/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009664{
9665 PyObject *bytes = NULL;
9666 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009667 const char *name_string = PyBytes_AS_STRING(name);
9668 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009669
Serhiy Storchaka77703942017-06-25 07:33:01 +03009670 if (strchr(name_string, '=') != NULL) {
9671 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9672 return NULL;
9673 }
Larry Hastings2f936352014-08-05 14:04:04 +10009674 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9675 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009676 return NULL;
9677 }
9678
9679 env = PyBytes_AS_STRING(bytes);
9680 if (putenv(env)) {
9681 Py_DECREF(bytes);
9682 return posix_error();
9683 }
9684
9685 posix_putenv_garbage_setitem(name, bytes);
9686 Py_RETURN_NONE;
9687}
9688#endif /* MS_WINDOWS */
9689#endif /* HAVE_PUTENV */
9690
9691
9692#ifdef HAVE_UNSETENV
9693/*[clinic input]
9694os.unsetenv
9695 name: FSConverter
9696 /
9697
9698Delete an environment variable.
9699[clinic start generated code]*/
9700
Larry Hastings2f936352014-08-05 14:04:04 +10009701static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009702os_unsetenv_impl(PyObject *module, PyObject *name)
9703/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009704{
Victor Stinner984890f2011-11-24 13:53:38 +01009705#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009706 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009707#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009708
Victor Stinner984890f2011-11-24 13:53:38 +01009709#ifdef HAVE_BROKEN_UNSETENV
9710 unsetenv(PyBytes_AS_STRING(name));
9711#else
Victor Stinner65170952011-11-22 22:16:17 +01009712 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009713 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009714 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009715#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009716
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 /* Remove the key from posix_putenv_garbage;
9718 * this will cause it to be collected. This has to
9719 * happen after the real unsetenv() call because the
9720 * old value was still accessible until then.
9721 */
Victor Stinner65170952011-11-22 22:16:17 +01009722 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 /* really not much we can do; just leak */
9724 PyErr_Clear();
9725 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009726 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009727}
Larry Hastings2f936352014-08-05 14:04:04 +10009728#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009729
Larry Hastings2f936352014-08-05 14:04:04 +10009730
9731/*[clinic input]
9732os.strerror
9733
9734 code: int
9735 /
9736
9737Translate an error code to a message string.
9738[clinic start generated code]*/
9739
Larry Hastings2f936352014-08-05 14:04:04 +10009740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009741os_strerror_impl(PyObject *module, int code)
9742/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009743{
9744 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 if (message == NULL) {
9746 PyErr_SetString(PyExc_ValueError,
9747 "strerror() argument out of range");
9748 return NULL;
9749 }
Victor Stinner1b579672011-12-17 05:47:23 +01009750 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009751}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009752
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009753
Guido van Rossumc9641791998-08-04 15:26:23 +00009754#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009755#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009756/*[clinic input]
9757os.WCOREDUMP -> bool
9758
9759 status: int
9760 /
9761
9762Return True if the process returning status was dumped to a core file.
9763[clinic start generated code]*/
9764
Larry Hastings2f936352014-08-05 14:04:04 +10009765static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009766os_WCOREDUMP_impl(PyObject *module, int status)
9767/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009768{
9769 WAIT_TYPE wait_status;
9770 WAIT_STATUS_INT(wait_status) = status;
9771 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009772}
9773#endif /* WCOREDUMP */
9774
Larry Hastings2f936352014-08-05 14:04:04 +10009775
Fred Drake106c1a02002-04-23 15:58:02 +00009776#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009777/*[clinic input]
9778os.WIFCONTINUED -> bool
9779
9780 status: int
9781
9782Return True if a particular process was continued from a job control stop.
9783
9784Return True if the process returning status was continued from a
9785job control stop.
9786[clinic start generated code]*/
9787
Larry Hastings2f936352014-08-05 14:04:04 +10009788static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009789os_WIFCONTINUED_impl(PyObject *module, int status)
9790/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009791{
9792 WAIT_TYPE wait_status;
9793 WAIT_STATUS_INT(wait_status) = status;
9794 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009795}
9796#endif /* WIFCONTINUED */
9797
Larry Hastings2f936352014-08-05 14:04:04 +10009798
Guido van Rossumc9641791998-08-04 15:26:23 +00009799#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009800/*[clinic input]
9801os.WIFSTOPPED -> bool
9802
9803 status: int
9804
9805Return True if the process returning status was stopped.
9806[clinic start generated code]*/
9807
Larry Hastings2f936352014-08-05 14:04:04 +10009808static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009809os_WIFSTOPPED_impl(PyObject *module, int status)
9810/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009811{
9812 WAIT_TYPE wait_status;
9813 WAIT_STATUS_INT(wait_status) = status;
9814 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009815}
9816#endif /* WIFSTOPPED */
9817
Larry Hastings2f936352014-08-05 14:04:04 +10009818
Guido van Rossumc9641791998-08-04 15:26:23 +00009819#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009820/*[clinic input]
9821os.WIFSIGNALED -> bool
9822
9823 status: int
9824
9825Return True if the process returning status was terminated by a signal.
9826[clinic start generated code]*/
9827
Larry Hastings2f936352014-08-05 14:04:04 +10009828static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009829os_WIFSIGNALED_impl(PyObject *module, int status)
9830/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009831{
9832 WAIT_TYPE wait_status;
9833 WAIT_STATUS_INT(wait_status) = status;
9834 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009835}
9836#endif /* WIFSIGNALED */
9837
Larry Hastings2f936352014-08-05 14:04:04 +10009838
Guido van Rossumc9641791998-08-04 15:26:23 +00009839#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009840/*[clinic input]
9841os.WIFEXITED -> bool
9842
9843 status: int
9844
9845Return True if the process returning status exited via the exit() system call.
9846[clinic start generated code]*/
9847
Larry Hastings2f936352014-08-05 14:04:04 +10009848static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009849os_WIFEXITED_impl(PyObject *module, int status)
9850/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009851{
9852 WAIT_TYPE wait_status;
9853 WAIT_STATUS_INT(wait_status) = status;
9854 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009855}
9856#endif /* WIFEXITED */
9857
Larry Hastings2f936352014-08-05 14:04:04 +10009858
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009859#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009860/*[clinic input]
9861os.WEXITSTATUS -> int
9862
9863 status: int
9864
9865Return the process return code from status.
9866[clinic start generated code]*/
9867
Larry Hastings2f936352014-08-05 14:04:04 +10009868static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009869os_WEXITSTATUS_impl(PyObject *module, int status)
9870/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009871{
9872 WAIT_TYPE wait_status;
9873 WAIT_STATUS_INT(wait_status) = status;
9874 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009875}
9876#endif /* WEXITSTATUS */
9877
Larry Hastings2f936352014-08-05 14:04:04 +10009878
Guido van Rossumc9641791998-08-04 15:26:23 +00009879#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009880/*[clinic input]
9881os.WTERMSIG -> int
9882
9883 status: int
9884
9885Return the signal that terminated the process that provided the status value.
9886[clinic start generated code]*/
9887
Larry Hastings2f936352014-08-05 14:04:04 +10009888static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009889os_WTERMSIG_impl(PyObject *module, int status)
9890/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009891{
9892 WAIT_TYPE wait_status;
9893 WAIT_STATUS_INT(wait_status) = status;
9894 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009895}
9896#endif /* WTERMSIG */
9897
Larry Hastings2f936352014-08-05 14:04:04 +10009898
Guido van Rossumc9641791998-08-04 15:26:23 +00009899#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009900/*[clinic input]
9901os.WSTOPSIG -> int
9902
9903 status: int
9904
9905Return the signal that stopped the process that provided the status value.
9906[clinic start generated code]*/
9907
Larry Hastings2f936352014-08-05 14:04:04 +10009908static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009909os_WSTOPSIG_impl(PyObject *module, int status)
9910/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009911{
9912 WAIT_TYPE wait_status;
9913 WAIT_STATUS_INT(wait_status) = status;
9914 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009915}
9916#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009917#endif /* HAVE_SYS_WAIT_H */
9918
9919
Thomas Wouters477c8d52006-05-27 19:21:47 +00009920#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009921#ifdef _SCO_DS
9922/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9923 needed definitions in sys/statvfs.h */
9924#define _SVID3
9925#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009926#include <sys/statvfs.h>
9927
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009928static PyObject*
9929_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -08009930 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 if (v == NULL)
9932 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009933
9934#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9936 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9937 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9938 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9939 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9940 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9941 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9942 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9943 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9944 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009945#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9947 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9948 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009949 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009951 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009953 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009955 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009957 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009959 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9961 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009962#endif
Michael Felt502d5512018-01-05 13:01:58 +01009963/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9964 * (issue #32390). */
9965#if defined(_AIX) && defined(_ALL_SOURCE)
9966 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9967#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009968 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009969#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009970 if (PyErr_Occurred()) {
9971 Py_DECREF(v);
9972 return NULL;
9973 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009974
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009976}
9977
Larry Hastings2f936352014-08-05 14:04:04 +10009978
9979/*[clinic input]
9980os.fstatvfs
9981 fd: int
9982 /
9983
9984Perform an fstatvfs system call on the given fd.
9985
9986Equivalent to statvfs(fd).
9987[clinic start generated code]*/
9988
Larry Hastings2f936352014-08-05 14:04:04 +10009989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009990os_fstatvfs_impl(PyObject *module, int fd)
9991/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009992{
9993 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009994 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009996
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009997 do {
9998 Py_BEGIN_ALLOW_THREADS
9999 result = fstatvfs(fd, &st);
10000 Py_END_ALLOW_THREADS
10001 } while (result != 0 && errno == EINTR &&
10002 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010003 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010004 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010005
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010007}
Larry Hastings2f936352014-08-05 14:04:04 +100010008#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010009
10010
Thomas Wouters477c8d52006-05-27 19:21:47 +000010011#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010012#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010013/*[clinic input]
10014os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010015
Larry Hastings2f936352014-08-05 14:04:04 +100010016 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10017
10018Perform a statvfs system call on the given path.
10019
10020path may always be specified as a string.
10021On some platforms, path may also be specified as an open file descriptor.
10022 If this functionality is unavailable, using it raises an exception.
10023[clinic start generated code]*/
10024
Larry Hastings2f936352014-08-05 14:04:04 +100010025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010026os_statvfs_impl(PyObject *module, path_t *path)
10027/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010028{
10029 int result;
10030 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010031
10032 Py_BEGIN_ALLOW_THREADS
10033#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010034 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010035#ifdef __APPLE__
10036 /* handle weak-linking on Mac OS X 10.3 */
10037 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010038 fd_specified("statvfs", path->fd);
10039 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010040 }
10041#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010042 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010043 }
10044 else
10045#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010046 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010047 Py_END_ALLOW_THREADS
10048
10049 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010050 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010051 }
10052
Larry Hastings2f936352014-08-05 14:04:04 +100010053 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010054}
Larry Hastings2f936352014-08-05 14:04:04 +100010055#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10056
Guido van Rossum94f6f721999-01-06 18:42:14 +000010057
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010058#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010059/*[clinic input]
10060os._getdiskusage
10061
Steve Dower23ad6d02018-02-22 10:39:10 -080010062 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010063
10064Return disk usage statistics about the given path as a (total, free) tuple.
10065[clinic start generated code]*/
10066
Larry Hastings2f936352014-08-05 14:04:04 +100010067static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010068os__getdiskusage_impl(PyObject *module, path_t *path)
10069/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010070{
10071 BOOL retval;
10072 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010073 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010074
10075 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010076 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010077 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010078 if (retval == 0) {
10079 if (GetLastError() == ERROR_DIRECTORY) {
10080 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010081
Joe Pamerc8c02492018-09-25 10:57:36 -040010082 dir_path = PyMem_New(wchar_t, path->length + 1);
10083 if (dir_path == NULL) {
10084 return PyErr_NoMemory();
10085 }
10086
10087 wcscpy_s(dir_path, path->length + 1, path->wide);
10088
10089 if (_dirnameW(dir_path) != -1) {
10090 Py_BEGIN_ALLOW_THREADS
10091 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10092 Py_END_ALLOW_THREADS
10093 }
10094 /* Record the last error in case it's modified by PyMem_Free. */
10095 err = GetLastError();
10096 PyMem_Free(dir_path);
10097 if (retval) {
10098 goto success;
10099 }
10100 }
10101 return PyErr_SetFromWindowsErr(err);
10102 }
10103
10104success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010105 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10106}
Larry Hastings2f936352014-08-05 14:04:04 +100010107#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010108
10109
Fred Drakec9680921999-12-13 16:37:25 +000010110/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10111 * It maps strings representing configuration variable names to
10112 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010113 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010114 * rarely-used constants. There are three separate tables that use
10115 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010116 *
10117 * This code is always included, even if none of the interfaces that
10118 * need it are included. The #if hackery needed to avoid it would be
10119 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010120 */
10121struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010122 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010123 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010124};
10125
Fred Drake12c6e2d1999-12-14 21:25:03 +000010126static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010127conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010128 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010129{
Christian Heimes217cfd12007-12-02 14:31:20 +000010130 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010131 int value = _PyLong_AsInt(arg);
10132 if (value == -1 && PyErr_Occurred())
10133 return 0;
10134 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010135 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010136 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010137 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010138 /* look up the value in the table using a binary search */
10139 size_t lo = 0;
10140 size_t mid;
10141 size_t hi = tablesize;
10142 int cmp;
10143 const char *confname;
10144 if (!PyUnicode_Check(arg)) {
10145 PyErr_SetString(PyExc_TypeError,
10146 "configuration names must be strings or integers");
10147 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010149 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010150 if (confname == NULL)
10151 return 0;
10152 while (lo < hi) {
10153 mid = (lo + hi) / 2;
10154 cmp = strcmp(confname, table[mid].name);
10155 if (cmp < 0)
10156 hi = mid;
10157 else if (cmp > 0)
10158 lo = mid + 1;
10159 else {
10160 *valuep = table[mid].value;
10161 return 1;
10162 }
10163 }
10164 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10165 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010167}
10168
10169
10170#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10171static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010172#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010174#endif
10175#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010177#endif
Fred Drakec9680921999-12-13 16:37:25 +000010178#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010223#ifdef _PC_ACL_ENABLED
10224 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10225#endif
10226#ifdef _PC_MIN_HOLE_SIZE
10227 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10228#endif
10229#ifdef _PC_ALLOC_SIZE_MIN
10230 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10231#endif
10232#ifdef _PC_REC_INCR_XFER_SIZE
10233 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10234#endif
10235#ifdef _PC_REC_MAX_XFER_SIZE
10236 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10237#endif
10238#ifdef _PC_REC_MIN_XFER_SIZE
10239 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10240#endif
10241#ifdef _PC_REC_XFER_ALIGN
10242 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10243#endif
10244#ifdef _PC_SYMLINK_MAX
10245 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10246#endif
10247#ifdef _PC_XATTR_ENABLED
10248 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10249#endif
10250#ifdef _PC_XATTR_EXISTS
10251 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10252#endif
10253#ifdef _PC_TIMESTAMP_RESOLUTION
10254 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10255#endif
Fred Drakec9680921999-12-13 16:37:25 +000010256};
10257
Fred Drakec9680921999-12-13 16:37:25 +000010258static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010259conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010260{
10261 return conv_confname(arg, valuep, posix_constants_pathconf,
10262 sizeof(posix_constants_pathconf)
10263 / sizeof(struct constdef));
10264}
10265#endif
10266
Larry Hastings2f936352014-08-05 14:04:04 +100010267
Fred Drakec9680921999-12-13 16:37:25 +000010268#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010269/*[clinic input]
10270os.fpathconf -> long
10271
10272 fd: int
10273 name: path_confname
10274 /
10275
10276Return the configuration limit name for the file descriptor fd.
10277
10278If there is no limit, return -1.
10279[clinic start generated code]*/
10280
Larry Hastings2f936352014-08-05 14:04:04 +100010281static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010282os_fpathconf_impl(PyObject *module, int fd, int name)
10283/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010284{
10285 long limit;
10286
10287 errno = 0;
10288 limit = fpathconf(fd, name);
10289 if (limit == -1 && errno != 0)
10290 posix_error();
10291
10292 return limit;
10293}
10294#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010295
10296
10297#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010298/*[clinic input]
10299os.pathconf -> long
10300 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10301 name: path_confname
10302
10303Return the configuration limit name for the file or directory path.
10304
10305If there is no limit, return -1.
10306On some platforms, path may also be specified as an open file descriptor.
10307 If this functionality is unavailable, using it raises an exception.
10308[clinic start generated code]*/
10309
Larry Hastings2f936352014-08-05 14:04:04 +100010310static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010311os_pathconf_impl(PyObject *module, path_t *path, int name)
10312/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010313{
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010315
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010317#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010318 if (path->fd != -1)
10319 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010320 else
10321#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010322 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 if (limit == -1 && errno != 0) {
10324 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010325 /* could be a path or name problem */
10326 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010327 else
Larry Hastings2f936352014-08-05 14:04:04 +100010328 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 }
Larry Hastings2f936352014-08-05 14:04:04 +100010330
10331 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010332}
Larry Hastings2f936352014-08-05 14:04:04 +100010333#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010334
10335#ifdef HAVE_CONFSTR
10336static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010337#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010339#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010340#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010342#endif
10343#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010345#endif
Fred Draked86ed291999-12-15 15:34:33 +000010346#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010348#endif
10349#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010351#endif
10352#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010354#endif
10355#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010357#endif
Fred Drakec9680921999-12-13 16:37:25 +000010358#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
Fred Draked86ed291999-12-15 15:34:33 +000010382#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010384#endif
Fred Drakec9680921999-12-13 16:37:25 +000010385#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
Fred Draked86ed291999-12-15 15:34:33 +000010388#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010390#endif
10391#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010393#endif
10394#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010396#endif
10397#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010399#endif
Fred Drakec9680921999-12-13 16:37:25 +000010400#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
10430#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010432#endif
10433#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
Fred Draked86ed291999-12-15 15:34:33 +000010448#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010450#endif
10451#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010453#endif
10454#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010456#endif
10457#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010459#endif
10460#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010462#endif
10463#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010465#endif
10466#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010468#endif
10469#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010471#endif
10472#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010474#endif
10475#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010477#endif
10478#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010480#endif
10481#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010483#endif
10484#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010486#endif
Fred Drakec9680921999-12-13 16:37:25 +000010487};
10488
10489static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010490conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010491{
10492 return conv_confname(arg, valuep, posix_constants_confstr,
10493 sizeof(posix_constants_confstr)
10494 / sizeof(struct constdef));
10495}
10496
Larry Hastings2f936352014-08-05 14:04:04 +100010497
10498/*[clinic input]
10499os.confstr
10500
10501 name: confstr_confname
10502 /
10503
10504Return a string-valued system configuration variable.
10505[clinic start generated code]*/
10506
Larry Hastings2f936352014-08-05 14:04:04 +100010507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010508os_confstr_impl(PyObject *module, int name)
10509/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010510{
10511 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010512 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010513 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010514
Victor Stinnercb043522010-09-10 23:49:04 +000010515 errno = 0;
10516 len = confstr(name, buffer, sizeof(buffer));
10517 if (len == 0) {
10518 if (errno) {
10519 posix_error();
10520 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010521 }
10522 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010523 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010524 }
10525 }
Victor Stinnercb043522010-09-10 23:49:04 +000010526
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010527 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010528 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010529 char *buf = PyMem_Malloc(len);
10530 if (buf == NULL)
10531 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010532 len2 = confstr(name, buf, len);
10533 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010534 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010535 PyMem_Free(buf);
10536 }
10537 else
10538 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010539 return result;
10540}
Larry Hastings2f936352014-08-05 14:04:04 +100010541#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010542
10543
10544#ifdef HAVE_SYSCONF
10545static struct constdef posix_constants_sysconf[] = {
10546#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
10564#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
10567#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010569#endif
10570#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010572#endif
10573#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010575#endif
Fred Draked86ed291999-12-15 15:34:33 +000010576#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010578#endif
10579#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010581#endif
Fred Drakec9680921999-12-13 16:37:25 +000010582#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010584#endif
Fred Drakec9680921999-12-13 16:37:25 +000010585#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010587#endif
10588#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010590#endif
10591#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010593#endif
10594#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010596#endif
10597#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010599#endif
Fred Draked86ed291999-12-15 15:34:33 +000010600#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010602#endif
Fred Drakec9680921999-12-13 16:37:25 +000010603#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010605#endif
10606#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010608#endif
10609#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010611#endif
10612#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010614#endif
10615#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010617#endif
Fred Draked86ed291999-12-15 15:34:33 +000010618#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010620#endif
Fred Drakec9680921999-12-13 16:37:25 +000010621#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010623#endif
10624#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010626#endif
10627#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010628 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010629#endif
10630#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010632#endif
10633#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010635#endif
10636#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010638#endif
10639#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010641#endif
10642#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010644#endif
10645#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010647#endif
10648#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010650#endif
10651#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010653#endif
10654#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010655 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010656#endif
10657#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010658 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010659#endif
10660#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010661 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010662#endif
10663#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010665#endif
10666#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010668#endif
10669#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010671#endif
10672#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010674#endif
10675#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010677#endif
10678#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010680#endif
10681#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010683#endif
10684#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010686#endif
10687#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010689#endif
Fred Draked86ed291999-12-15 15:34:33 +000010690#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010692#endif
Fred Drakec9680921999-12-13 16:37:25 +000010693#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010695#endif
10696#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010698#endif
10699#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010701#endif
Fred Draked86ed291999-12-15 15:34:33 +000010702#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010704#endif
Fred Drakec9680921999-12-13 16:37:25 +000010705#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010707#endif
Fred Draked86ed291999-12-15 15:34:33 +000010708#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010710#endif
10711#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010713#endif
Fred Drakec9680921999-12-13 16:37:25 +000010714#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010716#endif
10717#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010719#endif
10720#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010722#endif
10723#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010725#endif
Fred Draked86ed291999-12-15 15:34:33 +000010726#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010728#endif
Fred Drakec9680921999-12-13 16:37:25 +000010729#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010731#endif
10732#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010734#endif
10735#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010737#endif
10738#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010740#endif
10741#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010743#endif
10744#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010746#endif
10747#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010749#endif
Fred Draked86ed291999-12-15 15:34:33 +000010750#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010752#endif
Fred Drakec9680921999-12-13 16:37:25 +000010753#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010755#endif
10756#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010758#endif
Fred Draked86ed291999-12-15 15:34:33 +000010759#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010761#endif
Fred Drakec9680921999-12-13 16:37:25 +000010762#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010764#endif
10765#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010767#endif
10768#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010770#endif
10771#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010773#endif
10774#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010776#endif
10777#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010779#endif
10780#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010782#endif
10783#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010785#endif
10786#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010788#endif
Fred Draked86ed291999-12-15 15:34:33 +000010789#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010791#endif
10792#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010794#endif
Fred Drakec9680921999-12-13 16:37:25 +000010795#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010797#endif
10798#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010800#endif
10801#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010803#endif
10804#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010806#endif
10807#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010809#endif
10810#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010812#endif
10813#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010815#endif
10816#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010818#endif
10819#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010821#endif
10822#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010824#endif
10825#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010827#endif
10828#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010830#endif
10831#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010833#endif
10834#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010836#endif
10837#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010839#endif
10840#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010842#endif
10843#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010845#endif
10846#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010848#endif
10849#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010851#endif
10852#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010854#endif
10855#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010857#endif
10858#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010860#endif
10861#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010863#endif
10864#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010866#endif
10867#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010869#endif
10870#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010872#endif
10873#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010875#endif
10876#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010878#endif
10879#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010881#endif
10882#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010884#endif
10885#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010887#endif
10888#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010890#endif
10891#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010893#endif
10894#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010896#endif
10897#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010899#endif
Fred Draked86ed291999-12-15 15:34:33 +000010900#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010902#endif
Fred Drakec9680921999-12-13 16:37:25 +000010903#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010905#endif
10906#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010908#endif
10909#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010911#endif
10912#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010914#endif
10915#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010917#endif
10918#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010920#endif
10921#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010923#endif
10924#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010926#endif
10927#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010929#endif
10930#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010931 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010932#endif
10933#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010935#endif
10936#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010937 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010938#endif
10939#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010940 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010941#endif
10942#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010944#endif
10945#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010946 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010947#endif
10948#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010950#endif
10951#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010953#endif
10954#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010956#endif
10957#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010959#endif
10960#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010962#endif
10963#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010965#endif
10966#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010968#endif
10969#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010971#endif
10972#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010974#endif
10975#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010977#endif
10978#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010980#endif
10981#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010983#endif
10984#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010986#endif
10987#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010989#endif
10990#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010992#endif
10993#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010995#endif
10996#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010998#endif
10999#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011000 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011001#endif
11002#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011003 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011004#endif
11005#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011007#endif
11008#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011009 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011010#endif
11011#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011012 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011013#endif
11014#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011015 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011016#endif
11017#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011018 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011019#endif
11020#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011021 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011022#endif
11023#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011024 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011025#endif
11026#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011027 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011028#endif
11029#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011030 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011031#endif
11032#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011033 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011034#endif
11035#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011036 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011037#endif
11038};
11039
11040static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011041conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011042{
11043 return conv_confname(arg, valuep, posix_constants_sysconf,
11044 sizeof(posix_constants_sysconf)
11045 / sizeof(struct constdef));
11046}
11047
Larry Hastings2f936352014-08-05 14:04:04 +100011048
11049/*[clinic input]
11050os.sysconf -> long
11051 name: sysconf_confname
11052 /
11053
11054Return an integer-valued system configuration variable.
11055[clinic start generated code]*/
11056
Larry Hastings2f936352014-08-05 14:04:04 +100011057static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011058os_sysconf_impl(PyObject *module, int name)
11059/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011060{
11061 long value;
11062
11063 errno = 0;
11064 value = sysconf(name);
11065 if (value == -1 && errno != 0)
11066 posix_error();
11067 return value;
11068}
11069#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011070
11071
Fred Drakebec628d1999-12-15 18:31:10 +000011072/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011073 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011074 * the exported dictionaries that are used to publish information about the
11075 * names available on the host platform.
11076 *
11077 * Sorting the table at runtime ensures that the table is properly ordered
11078 * when used, even for platforms we're not able to test on. It also makes
11079 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011080 */
Fred Drakebec628d1999-12-15 18:31:10 +000011081
11082static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011083cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011084{
11085 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011087 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011089
11090 return strcmp(c1->name, c2->name);
11091}
11092
11093static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011094setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011095 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011096{
Fred Drakebec628d1999-12-15 18:31:10 +000011097 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011098 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011099
11100 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11101 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011102 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011104
Barry Warsaw3155db32000-04-13 15:20:40 +000011105 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 PyObject *o = PyLong_FromLong(table[i].value);
11107 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11108 Py_XDECREF(o);
11109 Py_DECREF(d);
11110 return -1;
11111 }
11112 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011113 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011114 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011115}
11116
Fred Drakebec628d1999-12-15 18:31:10 +000011117/* Return -1 on failure, 0 on success. */
11118static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011119setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011120{
11121#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011122 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011123 sizeof(posix_constants_pathconf)
11124 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011125 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011126 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011127#endif
11128#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011129 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011130 sizeof(posix_constants_confstr)
11131 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011132 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011133 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011134#endif
11135#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011136 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011137 sizeof(posix_constants_sysconf)
11138 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011139 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011140 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011141#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011142 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011143}
Fred Draked86ed291999-12-15 15:34:33 +000011144
11145
Larry Hastings2f936352014-08-05 14:04:04 +100011146/*[clinic input]
11147os.abort
11148
11149Abort the interpreter immediately.
11150
11151This function 'dumps core' or otherwise fails in the hardest way possible
11152on the hosting operating system. This function never returns.
11153[clinic start generated code]*/
11154
Larry Hastings2f936352014-08-05 14:04:04 +100011155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011156os_abort_impl(PyObject *module)
11157/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011158{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011159 abort();
11160 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011161#ifndef __clang__
11162 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11163 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11164 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011165 Py_FatalError("abort() called from Python code didn't abort!");
11166 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011167#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011168}
Fred Drakebec628d1999-12-15 18:31:10 +000011169
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011170#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011171/* Grab ShellExecute dynamically from shell32 */
11172static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011173static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11174 LPCWSTR, INT);
11175static int
11176check_ShellExecute()
11177{
11178 HINSTANCE hShell32;
11179
11180 /* only recheck */
11181 if (-1 == has_ShellExecute) {
11182 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011183 /* Security note: this call is not vulnerable to "DLL hijacking".
11184 SHELL32 is part of "KnownDLLs" and so Windows always load
11185 the system SHELL32.DLL, even if there is another SHELL32.DLL
11186 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011187 hShell32 = LoadLibraryW(L"SHELL32");
11188 Py_END_ALLOW_THREADS
11189 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011190 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11191 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011192 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011193 } else {
11194 has_ShellExecute = 0;
11195 }
11196 }
11197 return has_ShellExecute;
11198}
11199
11200
Steve Dowercc16be82016-09-08 10:35:16 -070011201/*[clinic input]
11202os.startfile
11203 filepath: path_t
11204 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011205
Steve Dowercc16be82016-09-08 10:35:16 -070011206startfile(filepath [, operation])
11207
11208Start a file with its associated application.
11209
11210When "operation" is not specified or "open", this acts like
11211double-clicking the file in Explorer, or giving the file name as an
11212argument to the DOS "start" command: the file is opened with whatever
11213application (if any) its extension is associated.
11214When another "operation" is given, it specifies what should be done with
11215the file. A typical operation is "print".
11216
11217startfile returns as soon as the associated application is launched.
11218There is no option to wait for the application to close, and no way
11219to retrieve the application's exit status.
11220
11221The filepath is relative to the current directory. If you want to use
11222an absolute path, make sure the first character is not a slash ("/");
11223the underlying Win32 ShellExecute function doesn't work if it is.
11224[clinic start generated code]*/
11225
11226static PyObject *
11227os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
11228/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
11229{
11230 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011231
11232 if(!check_ShellExecute()) {
11233 /* If the OS doesn't have ShellExecute, return a
11234 NotImplementedError. */
11235 return PyErr_Format(PyExc_NotImplementedError,
11236 "startfile not available on this platform");
11237 }
11238
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011240 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011241 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 Py_END_ALLOW_THREADS
11243
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011245 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011246 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 }
Steve Dowercc16be82016-09-08 10:35:16 -070011248 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011249}
Larry Hastings2f936352014-08-05 14:04:04 +100011250#endif /* MS_WINDOWS */
11251
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011252
Martin v. Löwis438b5342002-12-27 10:16:42 +000011253#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011254/*[clinic input]
11255os.getloadavg
11256
11257Return average recent system load information.
11258
11259Return the number of processes in the system run queue averaged over
11260the last 1, 5, and 15 minutes as a tuple of three floats.
11261Raises OSError if the load average was unobtainable.
11262[clinic start generated code]*/
11263
Larry Hastings2f936352014-08-05 14:04:04 +100011264static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011265os_getloadavg_impl(PyObject *module)
11266/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011267{
11268 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011269 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011270 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11271 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011272 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011273 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011274}
Larry Hastings2f936352014-08-05 14:04:04 +100011275#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011276
Larry Hastings2f936352014-08-05 14:04:04 +100011277
11278/*[clinic input]
11279os.device_encoding
11280 fd: int
11281
11282Return a string describing the encoding of a terminal's file descriptor.
11283
11284The file descriptor must be attached to a terminal.
11285If the device is not a terminal, return None.
11286[clinic start generated code]*/
11287
Larry Hastings2f936352014-08-05 14:04:04 +100011288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011289os_device_encoding_impl(PyObject *module, int fd)
11290/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011291{
Brett Cannonefb00c02012-02-29 18:31:31 -050011292 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011293}
11294
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011295
Larry Hastings2f936352014-08-05 14:04:04 +100011296#ifdef HAVE_SETRESUID
11297/*[clinic input]
11298os.setresuid
11299
11300 ruid: uid_t
11301 euid: uid_t
11302 suid: uid_t
11303 /
11304
11305Set the current process's real, effective, and saved user ids.
11306[clinic start generated code]*/
11307
Larry Hastings2f936352014-08-05 14:04:04 +100011308static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011309os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11310/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011311{
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 if (setresuid(ruid, euid, suid) < 0)
11313 return posix_error();
11314 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011315}
Larry Hastings2f936352014-08-05 14:04:04 +100011316#endif /* HAVE_SETRESUID */
11317
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011318
11319#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011320/*[clinic input]
11321os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011322
Larry Hastings2f936352014-08-05 14:04:04 +100011323 rgid: gid_t
11324 egid: gid_t
11325 sgid: gid_t
11326 /
11327
11328Set the current process's real, effective, and saved group ids.
11329[clinic start generated code]*/
11330
Larry Hastings2f936352014-08-05 14:04:04 +100011331static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011332os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11333/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011334{
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 if (setresgid(rgid, egid, sgid) < 0)
11336 return posix_error();
11337 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011338}
Larry Hastings2f936352014-08-05 14:04:04 +100011339#endif /* HAVE_SETRESGID */
11340
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011341
11342#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011343/*[clinic input]
11344os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011345
Larry Hastings2f936352014-08-05 14:04:04 +100011346Return a tuple of the current process's real, effective, and saved user ids.
11347[clinic start generated code]*/
11348
Larry Hastings2f936352014-08-05 14:04:04 +100011349static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011350os_getresuid_impl(PyObject *module)
11351/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011352{
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 if (getresuid(&ruid, &euid, &suid) < 0)
11355 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011356 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11357 _PyLong_FromUid(euid),
11358 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011359}
Larry Hastings2f936352014-08-05 14:04:04 +100011360#endif /* HAVE_GETRESUID */
11361
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011362
11363#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011364/*[clinic input]
11365os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011366
Larry Hastings2f936352014-08-05 14:04:04 +100011367Return a tuple of the current process's real, effective, and saved group ids.
11368[clinic start generated code]*/
11369
Larry Hastings2f936352014-08-05 14:04:04 +100011370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011371os_getresgid_impl(PyObject *module)
11372/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011373{
11374 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 if (getresgid(&rgid, &egid, &sgid) < 0)
11376 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011377 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11378 _PyLong_FromGid(egid),
11379 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011380}
Larry Hastings2f936352014-08-05 14:04:04 +100011381#endif /* HAVE_GETRESGID */
11382
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011383
Benjamin Peterson9428d532011-09-14 11:45:52 -040011384#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011385/*[clinic input]
11386os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011387
Larry Hastings2f936352014-08-05 14:04:04 +100011388 path: path_t(allow_fd=True)
11389 attribute: path_t
11390 *
11391 follow_symlinks: bool = True
11392
11393Return the value of extended attribute attribute on path.
11394
BNMetricsb9427072018-11-02 15:20:19 +000011395path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011396If follow_symlinks is False, and the last element of the path is a symbolic
11397 link, getxattr will examine the symbolic link itself instead of the file
11398 the link points to.
11399
11400[clinic start generated code]*/
11401
Larry Hastings2f936352014-08-05 14:04:04 +100011402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011403os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011404 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011405/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011406{
11407 Py_ssize_t i;
11408 PyObject *buffer = NULL;
11409
11410 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11411 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011412
Larry Hastings9cf065c2012-06-22 16:30:09 -070011413 for (i = 0; ; i++) {
11414 void *ptr;
11415 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011416 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011417 Py_ssize_t buffer_size = buffer_sizes[i];
11418 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011419 path_error(path);
11420 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011421 }
11422 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11423 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011424 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011425 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011426
Larry Hastings9cf065c2012-06-22 16:30:09 -070011427 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011428 if (path->fd >= 0)
11429 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011430 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011431 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011432 else
Larry Hastings2f936352014-08-05 14:04:04 +100011433 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011434 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011435
Larry Hastings9cf065c2012-06-22 16:30:09 -070011436 if (result < 0) {
11437 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011438 if (errno == ERANGE)
11439 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011440 path_error(path);
11441 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011442 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011443
Larry Hastings9cf065c2012-06-22 16:30:09 -070011444 if (result != buffer_size) {
11445 /* Can only shrink. */
11446 _PyBytes_Resize(&buffer, result);
11447 }
11448 break;
11449 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011450
Larry Hastings9cf065c2012-06-22 16:30:09 -070011451 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011452}
11453
Larry Hastings2f936352014-08-05 14:04:04 +100011454
11455/*[clinic input]
11456os.setxattr
11457
11458 path: path_t(allow_fd=True)
11459 attribute: path_t
11460 value: Py_buffer
11461 flags: int = 0
11462 *
11463 follow_symlinks: bool = True
11464
11465Set extended attribute attribute on path to value.
11466
BNMetricsb9427072018-11-02 15:20:19 +000011467path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011468If follow_symlinks is False, and the last element of the path is a symbolic
11469 link, setxattr will modify the symbolic link itself instead of the file
11470 the link points to.
11471
11472[clinic start generated code]*/
11473
Benjamin Peterson799bd802011-08-31 22:15:17 -040011474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011475os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011476 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011477/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011478{
Larry Hastings2f936352014-08-05 14:04:04 +100011479 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011480
Larry Hastings2f936352014-08-05 14:04:04 +100011481 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011482 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011483
Benjamin Peterson799bd802011-08-31 22:15:17 -040011484 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011485 if (path->fd > -1)
11486 result = fsetxattr(path->fd, attribute->narrow,
11487 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011488 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011489 result = setxattr(path->narrow, attribute->narrow,
11490 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011491 else
Larry Hastings2f936352014-08-05 14:04:04 +100011492 result = lsetxattr(path->narrow, attribute->narrow,
11493 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011494 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011495
Larry Hastings9cf065c2012-06-22 16:30:09 -070011496 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011497 path_error(path);
11498 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011499 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011500
Larry Hastings2f936352014-08-05 14:04:04 +100011501 Py_RETURN_NONE;
11502}
11503
11504
11505/*[clinic input]
11506os.removexattr
11507
11508 path: path_t(allow_fd=True)
11509 attribute: path_t
11510 *
11511 follow_symlinks: bool = True
11512
11513Remove extended attribute attribute on path.
11514
BNMetricsb9427072018-11-02 15:20:19 +000011515path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011516If follow_symlinks is False, and the last element of the path is a symbolic
11517 link, removexattr will modify the symbolic link itself instead of the file
11518 the link points to.
11519
11520[clinic start generated code]*/
11521
Larry Hastings2f936352014-08-05 14:04:04 +100011522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011523os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011524 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011525/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011526{
11527 ssize_t result;
11528
11529 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11530 return NULL;
11531
11532 Py_BEGIN_ALLOW_THREADS;
11533 if (path->fd > -1)
11534 result = fremovexattr(path->fd, attribute->narrow);
11535 else if (follow_symlinks)
11536 result = removexattr(path->narrow, attribute->narrow);
11537 else
11538 result = lremovexattr(path->narrow, attribute->narrow);
11539 Py_END_ALLOW_THREADS;
11540
11541 if (result) {
11542 return path_error(path);
11543 }
11544
11545 Py_RETURN_NONE;
11546}
11547
11548
11549/*[clinic input]
11550os.listxattr
11551
11552 path: path_t(allow_fd=True, nullable=True) = None
11553 *
11554 follow_symlinks: bool = True
11555
11556Return a list of extended attributes on path.
11557
BNMetricsb9427072018-11-02 15:20:19 +000011558path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011559if path is None, listxattr will examine the current directory.
11560If follow_symlinks is False, and the last element of the path is a symbolic
11561 link, listxattr will examine the symbolic link itself instead of the file
11562 the link points to.
11563[clinic start generated code]*/
11564
Larry Hastings2f936352014-08-05 14:04:04 +100011565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011566os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011567/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011568{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011569 Py_ssize_t i;
11570 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011571 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011572 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011573
Larry Hastings2f936352014-08-05 14:04:04 +100011574 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011575 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011576
Larry Hastings2f936352014-08-05 14:04:04 +100011577 name = path->narrow ? path->narrow : ".";
11578
Larry Hastings9cf065c2012-06-22 16:30:09 -070011579 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011580 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011581 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011582 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011583 Py_ssize_t buffer_size = buffer_sizes[i];
11584 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011585 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011586 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011587 break;
11588 }
11589 buffer = PyMem_MALLOC(buffer_size);
11590 if (!buffer) {
11591 PyErr_NoMemory();
11592 break;
11593 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011594
Larry Hastings9cf065c2012-06-22 16:30:09 -070011595 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011596 if (path->fd > -1)
11597 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011598 else if (follow_symlinks)
11599 length = listxattr(name, buffer, buffer_size);
11600 else
11601 length = llistxattr(name, buffer, buffer_size);
11602 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011603
Larry Hastings9cf065c2012-06-22 16:30:09 -070011604 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011605 if (errno == ERANGE) {
11606 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011607 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011608 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011609 }
Larry Hastings2f936352014-08-05 14:04:04 +100011610 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011611 break;
11612 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011613
Larry Hastings9cf065c2012-06-22 16:30:09 -070011614 result = PyList_New(0);
11615 if (!result) {
11616 goto exit;
11617 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011618
Larry Hastings9cf065c2012-06-22 16:30:09 -070011619 end = buffer + length;
11620 for (trace = start = buffer; trace != end; trace++) {
11621 if (!*trace) {
11622 int error;
11623 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11624 trace - start);
11625 if (!attribute) {
11626 Py_DECREF(result);
11627 result = NULL;
11628 goto exit;
11629 }
11630 error = PyList_Append(result, attribute);
11631 Py_DECREF(attribute);
11632 if (error) {
11633 Py_DECREF(result);
11634 result = NULL;
11635 goto exit;
11636 }
11637 start = trace + 1;
11638 }
11639 }
11640 break;
11641 }
11642exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011643 if (buffer)
11644 PyMem_FREE(buffer);
11645 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011646}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011647#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011648
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011649
Larry Hastings2f936352014-08-05 14:04:04 +100011650/*[clinic input]
11651os.urandom
11652
11653 size: Py_ssize_t
11654 /
11655
11656Return a bytes object containing random bytes suitable for cryptographic use.
11657[clinic start generated code]*/
11658
Larry Hastings2f936352014-08-05 14:04:04 +100011659static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011660os_urandom_impl(PyObject *module, Py_ssize_t size)
11661/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011662{
11663 PyObject *bytes;
11664 int result;
11665
Georg Brandl2fb477c2012-02-21 00:33:36 +010011666 if (size < 0)
11667 return PyErr_Format(PyExc_ValueError,
11668 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011669 bytes = PyBytes_FromStringAndSize(NULL, size);
11670 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011671 return NULL;
11672
Victor Stinnere66987e2016-09-06 16:33:52 -070011673 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011674 if (result == -1) {
11675 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011676 return NULL;
11677 }
Larry Hastings2f936352014-08-05 14:04:04 +100011678 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011679}
11680
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011681/* Terminal size querying */
11682
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011683static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011684
11685PyDoc_STRVAR(TerminalSize_docstring,
11686 "A tuple of (columns, lines) for holding terminal window size");
11687
11688static PyStructSequence_Field TerminalSize_fields[] = {
11689 {"columns", "width of the terminal window in characters"},
11690 {"lines", "height of the terminal window in characters"},
11691 {NULL, NULL}
11692};
11693
11694static PyStructSequence_Desc TerminalSize_desc = {
11695 "os.terminal_size",
11696 TerminalSize_docstring,
11697 TerminalSize_fields,
11698 2,
11699};
11700
11701#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011702/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011703PyDoc_STRVAR(termsize__doc__,
11704 "Return the size of the terminal window as (columns, lines).\n" \
11705 "\n" \
11706 "The optional argument fd (default standard output) specifies\n" \
11707 "which file descriptor should be queried.\n" \
11708 "\n" \
11709 "If the file descriptor is not connected to a terminal, an OSError\n" \
11710 "is thrown.\n" \
11711 "\n" \
11712 "This function will only be defined if an implementation is\n" \
11713 "available for this system.\n" \
11714 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011715 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011716 "normally be used, os.get_terminal_size is the low-level implementation.");
11717
11718static PyObject*
11719get_terminal_size(PyObject *self, PyObject *args)
11720{
11721 int columns, lines;
11722 PyObject *termsize;
11723
11724 int fd = fileno(stdout);
11725 /* Under some conditions stdout may not be connected and
11726 * fileno(stdout) may point to an invalid file descriptor. For example
11727 * GUI apps don't have valid standard streams by default.
11728 *
11729 * If this happens, and the optional fd argument is not present,
11730 * the ioctl below will fail returning EBADF. This is what we want.
11731 */
11732
11733 if (!PyArg_ParseTuple(args, "|i", &fd))
11734 return NULL;
11735
11736#ifdef TERMSIZE_USE_IOCTL
11737 {
11738 struct winsize w;
11739 if (ioctl(fd, TIOCGWINSZ, &w))
11740 return PyErr_SetFromErrno(PyExc_OSError);
11741 columns = w.ws_col;
11742 lines = w.ws_row;
11743 }
11744#endif /* TERMSIZE_USE_IOCTL */
11745
11746#ifdef TERMSIZE_USE_CONIO
11747 {
11748 DWORD nhandle;
11749 HANDLE handle;
11750 CONSOLE_SCREEN_BUFFER_INFO csbi;
11751 switch (fd) {
11752 case 0: nhandle = STD_INPUT_HANDLE;
11753 break;
11754 case 1: nhandle = STD_OUTPUT_HANDLE;
11755 break;
11756 case 2: nhandle = STD_ERROR_HANDLE;
11757 break;
11758 default:
11759 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11760 }
11761 handle = GetStdHandle(nhandle);
11762 if (handle == NULL)
11763 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11764 if (handle == INVALID_HANDLE_VALUE)
11765 return PyErr_SetFromWindowsErr(0);
11766
11767 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11768 return PyErr_SetFromWindowsErr(0);
11769
11770 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11771 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11772 }
11773#endif /* TERMSIZE_USE_CONIO */
11774
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011775 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011776 if (termsize == NULL)
11777 return NULL;
11778 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11779 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11780 if (PyErr_Occurred()) {
11781 Py_DECREF(termsize);
11782 return NULL;
11783 }
11784 return termsize;
11785}
11786#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11787
Larry Hastings2f936352014-08-05 14:04:04 +100011788
11789/*[clinic input]
11790os.cpu_count
11791
Charles-François Natali80d62e62015-08-13 20:37:08 +010011792Return the number of CPUs in the system; return None if indeterminable.
11793
11794This number is not equivalent to the number of CPUs the current process can
11795use. The number of usable CPUs can be obtained with
11796``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011797[clinic start generated code]*/
11798
Larry Hastings2f936352014-08-05 14:04:04 +100011799static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011800os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011801/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011802{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011803 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011804#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011805 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11806 Need to fallback to Vista behavior if this call isn't present */
11807 HINSTANCE hKernel32;
11808 hKernel32 = GetModuleHandleW(L"KERNEL32");
11809
11810 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11811 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11812 "GetMaximumProcessorCount");
11813 if (_GetMaximumProcessorCount != NULL) {
11814 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11815 }
11816 else {
11817 SYSTEM_INFO sysinfo;
11818 GetSystemInfo(&sysinfo);
11819 ncpu = sysinfo.dwNumberOfProcessors;
11820 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011821#elif defined(__hpux)
11822 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11823#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11824 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011825#elif defined(__DragonFly__) || \
11826 defined(__OpenBSD__) || \
11827 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011828 defined(__NetBSD__) || \
11829 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011830 int mib[2];
11831 size_t len = sizeof(ncpu);
11832 mib[0] = CTL_HW;
11833 mib[1] = HW_NCPU;
11834 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11835 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011836#endif
11837 if (ncpu >= 1)
11838 return PyLong_FromLong(ncpu);
11839 else
11840 Py_RETURN_NONE;
11841}
11842
Victor Stinnerdaf45552013-08-28 00:53:59 +020011843
Larry Hastings2f936352014-08-05 14:04:04 +100011844/*[clinic input]
11845os.get_inheritable -> bool
11846
11847 fd: int
11848 /
11849
11850Get the close-on-exe flag of the specified file descriptor.
11851[clinic start generated code]*/
11852
Larry Hastings2f936352014-08-05 14:04:04 +100011853static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011854os_get_inheritable_impl(PyObject *module, int fd)
11855/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011856{
Steve Dower8fc89802015-04-12 00:26:27 -040011857 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011858 _Py_BEGIN_SUPPRESS_IPH
11859 return_value = _Py_get_inheritable(fd);
11860 _Py_END_SUPPRESS_IPH
11861 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011862}
11863
11864
11865/*[clinic input]
11866os.set_inheritable
11867 fd: int
11868 inheritable: int
11869 /
11870
11871Set the inheritable flag of the specified file descriptor.
11872[clinic start generated code]*/
11873
Larry Hastings2f936352014-08-05 14:04:04 +100011874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011875os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11876/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011877{
Steve Dower8fc89802015-04-12 00:26:27 -040011878 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011879
Steve Dower8fc89802015-04-12 00:26:27 -040011880 _Py_BEGIN_SUPPRESS_IPH
11881 result = _Py_set_inheritable(fd, inheritable, NULL);
11882 _Py_END_SUPPRESS_IPH
11883 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011884 return NULL;
11885 Py_RETURN_NONE;
11886}
11887
11888
11889#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011890/*[clinic input]
11891os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011892 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011893 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011894
Larry Hastings2f936352014-08-05 14:04:04 +100011895Get the close-on-exe flag of the specified file descriptor.
11896[clinic start generated code]*/
11897
Larry Hastings2f936352014-08-05 14:04:04 +100011898static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011899os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011900/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011901{
11902 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011903
11904 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11905 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011906 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011907 }
11908
Larry Hastings2f936352014-08-05 14:04:04 +100011909 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011910}
11911
Victor Stinnerdaf45552013-08-28 00:53:59 +020011912
Larry Hastings2f936352014-08-05 14:04:04 +100011913/*[clinic input]
11914os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011915 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011916 inheritable: bool
11917 /
11918
11919Set the inheritable flag of the specified handle.
11920[clinic start generated code]*/
11921
Larry Hastings2f936352014-08-05 14:04:04 +100011922static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011923os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011924 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011925/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011926{
11927 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011928 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11929 PyErr_SetFromWindowsErr(0);
11930 return NULL;
11931 }
11932 Py_RETURN_NONE;
11933}
Larry Hastings2f936352014-08-05 14:04:04 +100011934#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011935
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011936#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011937/*[clinic input]
11938os.get_blocking -> bool
11939 fd: int
11940 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011941
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011942Get the blocking mode of the file descriptor.
11943
11944Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
11945[clinic start generated code]*/
11946
11947static int
11948os_get_blocking_impl(PyObject *module, int fd)
11949/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011950{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011951 int blocking;
11952
Steve Dower8fc89802015-04-12 00:26:27 -040011953 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011954 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011955 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011956 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011957}
11958
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011959/*[clinic input]
11960os.set_blocking
11961 fd: int
11962 blocking: bool(accept={int})
11963 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011964
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011965Set the blocking mode of the specified file descriptor.
11966
11967Set the O_NONBLOCK flag if blocking is False,
11968clear the O_NONBLOCK flag otherwise.
11969[clinic start generated code]*/
11970
11971static PyObject *
11972os_set_blocking_impl(PyObject *module, int fd, int blocking)
11973/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011974{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011975 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011976
Steve Dower8fc89802015-04-12 00:26:27 -040011977 _Py_BEGIN_SUPPRESS_IPH
11978 result = _Py_set_blocking(fd, blocking);
11979 _Py_END_SUPPRESS_IPH
11980 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011981 return NULL;
11982 Py_RETURN_NONE;
11983}
11984#endif /* !MS_WINDOWS */
11985
11986
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011987/*[clinic input]
11988class os.DirEntry "DirEntry *" "&DirEntryType"
11989[clinic start generated code]*/
11990/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011991
11992typedef struct {
11993 PyObject_HEAD
11994 PyObject *name;
11995 PyObject *path;
11996 PyObject *stat;
11997 PyObject *lstat;
11998#ifdef MS_WINDOWS
11999 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012000 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012001 int got_file_index;
12002#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012003#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012004 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012005#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012006 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012007 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012008#endif
12009} DirEntry;
12010
12011static void
12012DirEntry_dealloc(DirEntry *entry)
12013{
12014 Py_XDECREF(entry->name);
12015 Py_XDECREF(entry->path);
12016 Py_XDECREF(entry->stat);
12017 Py_XDECREF(entry->lstat);
12018 Py_TYPE(entry)->tp_free((PyObject *)entry);
12019}
12020
12021/* Forward reference */
12022static int
12023DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12024
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012025/*[clinic input]
12026os.DirEntry.is_symlink -> bool
12027
12028Return True if the entry is a symbolic link; cached per entry.
12029[clinic start generated code]*/
12030
Victor Stinner6036e442015-03-08 01:58:04 +010012031static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012032os_DirEntry_is_symlink_impl(DirEntry *self)
12033/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012034{
12035#ifdef MS_WINDOWS
12036 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012037#elif defined(HAVE_DIRENT_D_TYPE)
12038 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012039 if (self->d_type != DT_UNKNOWN)
12040 return self->d_type == DT_LNK;
12041 else
12042 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012043#else
12044 /* POSIX without d_type */
12045 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012046#endif
12047}
12048
12049static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012050DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12051{
12052 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012053 STRUCT_STAT st;
12054 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012055
12056#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012057 if (!PyUnicode_FSDecoder(self->path, &ub))
12058 return NULL;
12059 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012060#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012061 if (!PyUnicode_FSConverter(self->path, &ub))
12062 return NULL;
12063 const char *path = PyBytes_AS_STRING(ub);
12064 if (self->dir_fd != DEFAULT_DIR_FD) {
12065#ifdef HAVE_FSTATAT
12066 result = fstatat(self->dir_fd, path, &st,
12067 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12068#else
12069 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12070 return NULL;
12071#endif /* HAVE_FSTATAT */
12072 }
12073 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012074#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012075 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012076 if (follow_symlinks)
12077 result = STAT(path, &st);
12078 else
12079 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012080 }
12081 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012082
12083 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012084 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012085
12086 return _pystat_fromstructstat(&st);
12087}
12088
12089static PyObject *
12090DirEntry_get_lstat(DirEntry *self)
12091{
12092 if (!self->lstat) {
12093#ifdef MS_WINDOWS
12094 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12095#else /* POSIX */
12096 self->lstat = DirEntry_fetch_stat(self, 0);
12097#endif
12098 }
12099 Py_XINCREF(self->lstat);
12100 return self->lstat;
12101}
12102
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012103/*[clinic input]
12104os.DirEntry.stat
12105 *
12106 follow_symlinks: bool = True
12107
12108Return stat_result object for the entry; cached per entry.
12109[clinic start generated code]*/
12110
Victor Stinner6036e442015-03-08 01:58:04 +010012111static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012112os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12113/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012114{
12115 if (!follow_symlinks)
12116 return DirEntry_get_lstat(self);
12117
12118 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012119 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012120 if (result == -1)
12121 return NULL;
12122 else if (result)
12123 self->stat = DirEntry_fetch_stat(self, 1);
12124 else
12125 self->stat = DirEntry_get_lstat(self);
12126 }
12127
12128 Py_XINCREF(self->stat);
12129 return self->stat;
12130}
12131
Victor Stinner6036e442015-03-08 01:58:04 +010012132/* Set exception and return -1 on error, 0 for False, 1 for True */
12133static int
12134DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12135{
12136 PyObject *stat = NULL;
12137 PyObject *st_mode = NULL;
12138 long mode;
12139 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012140#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012141 int is_symlink;
12142 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012143#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012144#ifdef MS_WINDOWS
12145 unsigned long dir_bits;
12146#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012147 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012148
12149#ifdef MS_WINDOWS
12150 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12151 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012152#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012153 is_symlink = self->d_type == DT_LNK;
12154 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12155#endif
12156
Victor Stinner35a97c02015-03-08 02:59:09 +010012157#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012158 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012159#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012160 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012161 if (!stat) {
12162 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12163 /* If file doesn't exist (anymore), then return False
12164 (i.e., say it's not a file/directory) */
12165 PyErr_Clear();
12166 return 0;
12167 }
12168 goto error;
12169 }
12170 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12171 if (!st_mode)
12172 goto error;
12173
12174 mode = PyLong_AsLong(st_mode);
12175 if (mode == -1 && PyErr_Occurred())
12176 goto error;
12177 Py_CLEAR(st_mode);
12178 Py_CLEAR(stat);
12179 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012180#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012181 }
12182 else if (is_symlink) {
12183 assert(mode_bits != S_IFLNK);
12184 result = 0;
12185 }
12186 else {
12187 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12188#ifdef MS_WINDOWS
12189 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12190 if (mode_bits == S_IFDIR)
12191 result = dir_bits != 0;
12192 else
12193 result = dir_bits == 0;
12194#else /* POSIX */
12195 if (mode_bits == S_IFDIR)
12196 result = self->d_type == DT_DIR;
12197 else
12198 result = self->d_type == DT_REG;
12199#endif
12200 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012201#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012202
12203 return result;
12204
12205error:
12206 Py_XDECREF(st_mode);
12207 Py_XDECREF(stat);
12208 return -1;
12209}
12210
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012211/*[clinic input]
12212os.DirEntry.is_dir -> bool
12213 *
12214 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012215
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012216Return True if the entry is a directory; cached per entry.
12217[clinic start generated code]*/
12218
12219static int
12220os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12221/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12222{
12223 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012224}
12225
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012226/*[clinic input]
12227os.DirEntry.is_file -> bool
12228 *
12229 follow_symlinks: bool = True
12230
12231Return True if the entry is a file; cached per entry.
12232[clinic start generated code]*/
12233
12234static int
12235os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12236/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012237{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012238 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012239}
12240
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012241/*[clinic input]
12242os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012243
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012244Return inode of the entry; cached per entry.
12245[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012246
12247static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012248os_DirEntry_inode_impl(DirEntry *self)
12249/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012250{
12251#ifdef MS_WINDOWS
12252 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012253 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012254 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012255 STRUCT_STAT stat;
12256 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012257
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012258 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012259 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012260 path = PyUnicode_AsUnicode(unicode);
12261 result = LSTAT(path, &stat);
12262 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012263
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012264 if (result != 0)
12265 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012266
12267 self->win32_file_index = stat.st_ino;
12268 self->got_file_index = 1;
12269 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012270 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12271 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012272#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012273 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12274 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012275#endif
12276}
12277
12278static PyObject *
12279DirEntry_repr(DirEntry *self)
12280{
12281 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12282}
12283
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012284/*[clinic input]
12285os.DirEntry.__fspath__
12286
12287Returns the path for the entry.
12288[clinic start generated code]*/
12289
Brett Cannon96881cd2016-06-10 14:37:21 -070012290static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012291os_DirEntry___fspath___impl(DirEntry *self)
12292/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012293{
12294 Py_INCREF(self->path);
12295 return self->path;
12296}
12297
Victor Stinner6036e442015-03-08 01:58:04 +010012298static PyMemberDef DirEntry_members[] = {
12299 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12300 "the entry's base filename, relative to scandir() \"path\" argument"},
12301 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12302 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12303 {NULL}
12304};
12305
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012306#include "clinic/posixmodule.c.h"
12307
Victor Stinner6036e442015-03-08 01:58:04 +010012308static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012309 OS_DIRENTRY_IS_DIR_METHODDEF
12310 OS_DIRENTRY_IS_FILE_METHODDEF
12311 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12312 OS_DIRENTRY_STAT_METHODDEF
12313 OS_DIRENTRY_INODE_METHODDEF
12314 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012315 {NULL}
12316};
12317
Benjamin Peterson5646de42015-04-12 17:56:34 -040012318static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012319 PyVarObject_HEAD_INIT(NULL, 0)
12320 MODNAME ".DirEntry", /* tp_name */
12321 sizeof(DirEntry), /* tp_basicsize */
12322 0, /* tp_itemsize */
12323 /* methods */
12324 (destructor)DirEntry_dealloc, /* tp_dealloc */
12325 0, /* tp_print */
12326 0, /* tp_getattr */
12327 0, /* tp_setattr */
12328 0, /* tp_compare */
12329 (reprfunc)DirEntry_repr, /* tp_repr */
12330 0, /* tp_as_number */
12331 0, /* tp_as_sequence */
12332 0, /* tp_as_mapping */
12333 0, /* tp_hash */
12334 0, /* tp_call */
12335 0, /* tp_str */
12336 0, /* tp_getattro */
12337 0, /* tp_setattro */
12338 0, /* tp_as_buffer */
12339 Py_TPFLAGS_DEFAULT, /* tp_flags */
12340 0, /* tp_doc */
12341 0, /* tp_traverse */
12342 0, /* tp_clear */
12343 0, /* tp_richcompare */
12344 0, /* tp_weaklistoffset */
12345 0, /* tp_iter */
12346 0, /* tp_iternext */
12347 DirEntry_methods, /* tp_methods */
12348 DirEntry_members, /* tp_members */
12349};
12350
12351#ifdef MS_WINDOWS
12352
12353static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012354join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012355{
12356 Py_ssize_t path_len;
12357 Py_ssize_t size;
12358 wchar_t *result;
12359 wchar_t ch;
12360
12361 if (!path_wide) { /* Default arg: "." */
12362 path_wide = L".";
12363 path_len = 1;
12364 }
12365 else {
12366 path_len = wcslen(path_wide);
12367 }
12368
12369 /* The +1's are for the path separator and the NUL */
12370 size = path_len + 1 + wcslen(filename) + 1;
12371 result = PyMem_New(wchar_t, size);
12372 if (!result) {
12373 PyErr_NoMemory();
12374 return NULL;
12375 }
12376 wcscpy(result, path_wide);
12377 if (path_len > 0) {
12378 ch = result[path_len - 1];
12379 if (ch != SEP && ch != ALTSEP && ch != L':')
12380 result[path_len++] = SEP;
12381 wcscpy(result + path_len, filename);
12382 }
12383 return result;
12384}
12385
12386static PyObject *
12387DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12388{
12389 DirEntry *entry;
12390 BY_HANDLE_FILE_INFORMATION file_info;
12391 ULONG reparse_tag;
12392 wchar_t *joined_path;
12393
12394 entry = PyObject_New(DirEntry, &DirEntryType);
12395 if (!entry)
12396 return NULL;
12397 entry->name = NULL;
12398 entry->path = NULL;
12399 entry->stat = NULL;
12400 entry->lstat = NULL;
12401 entry->got_file_index = 0;
12402
12403 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12404 if (!entry->name)
12405 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012406 if (path->narrow) {
12407 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12408 if (!entry->name)
12409 goto error;
12410 }
Victor Stinner6036e442015-03-08 01:58:04 +010012411
12412 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12413 if (!joined_path)
12414 goto error;
12415
12416 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12417 PyMem_Free(joined_path);
12418 if (!entry->path)
12419 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012420 if (path->narrow) {
12421 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12422 if (!entry->path)
12423 goto error;
12424 }
Victor Stinner6036e442015-03-08 01:58:04 +010012425
Steve Dowercc16be82016-09-08 10:35:16 -070012426 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012427 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12428
12429 return (PyObject *)entry;
12430
12431error:
12432 Py_DECREF(entry);
12433 return NULL;
12434}
12435
12436#else /* POSIX */
12437
12438static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012439join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012440{
12441 Py_ssize_t path_len;
12442 Py_ssize_t size;
12443 char *result;
12444
12445 if (!path_narrow) { /* Default arg: "." */
12446 path_narrow = ".";
12447 path_len = 1;
12448 }
12449 else {
12450 path_len = strlen(path_narrow);
12451 }
12452
12453 if (filename_len == -1)
12454 filename_len = strlen(filename);
12455
12456 /* The +1's are for the path separator and the NUL */
12457 size = path_len + 1 + filename_len + 1;
12458 result = PyMem_New(char, size);
12459 if (!result) {
12460 PyErr_NoMemory();
12461 return NULL;
12462 }
12463 strcpy(result, path_narrow);
12464 if (path_len > 0 && result[path_len - 1] != '/')
12465 result[path_len++] = '/';
12466 strcpy(result + path_len, filename);
12467 return result;
12468}
12469
12470static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012471DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012472 ino_t d_ino
12473#ifdef HAVE_DIRENT_D_TYPE
12474 , unsigned char d_type
12475#endif
12476 )
Victor Stinner6036e442015-03-08 01:58:04 +010012477{
12478 DirEntry *entry;
12479 char *joined_path;
12480
12481 entry = PyObject_New(DirEntry, &DirEntryType);
12482 if (!entry)
12483 return NULL;
12484 entry->name = NULL;
12485 entry->path = NULL;
12486 entry->stat = NULL;
12487 entry->lstat = NULL;
12488
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012489 if (path->fd != -1) {
12490 entry->dir_fd = path->fd;
12491 joined_path = NULL;
12492 }
12493 else {
12494 entry->dir_fd = DEFAULT_DIR_FD;
12495 joined_path = join_path_filename(path->narrow, name, name_len);
12496 if (!joined_path)
12497 goto error;
12498 }
Victor Stinner6036e442015-03-08 01:58:04 +010012499
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012500 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012501 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012502 if (joined_path)
12503 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012504 }
12505 else {
12506 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012507 if (joined_path)
12508 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012509 }
12510 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012511 if (!entry->name)
12512 goto error;
12513
12514 if (path->fd != -1) {
12515 entry->path = entry->name;
12516 Py_INCREF(entry->path);
12517 }
12518 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012519 goto error;
12520
Victor Stinner35a97c02015-03-08 02:59:09 +010012521#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012522 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012523#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012524 entry->d_ino = d_ino;
12525
12526 return (PyObject *)entry;
12527
12528error:
12529 Py_XDECREF(entry);
12530 return NULL;
12531}
12532
12533#endif
12534
12535
12536typedef struct {
12537 PyObject_HEAD
12538 path_t path;
12539#ifdef MS_WINDOWS
12540 HANDLE handle;
12541 WIN32_FIND_DATAW file_data;
12542 int first_time;
12543#else /* POSIX */
12544 DIR *dirp;
12545#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012546#ifdef HAVE_FDOPENDIR
12547 int fd;
12548#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012549} ScandirIterator;
12550
12551#ifdef MS_WINDOWS
12552
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012553static int
12554ScandirIterator_is_closed(ScandirIterator *iterator)
12555{
12556 return iterator->handle == INVALID_HANDLE_VALUE;
12557}
12558
Victor Stinner6036e442015-03-08 01:58:04 +010012559static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012560ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012561{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012562 HANDLE handle = iterator->handle;
12563
12564 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012565 return;
12566
Victor Stinner6036e442015-03-08 01:58:04 +010012567 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012568 Py_BEGIN_ALLOW_THREADS
12569 FindClose(handle);
12570 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012571}
12572
12573static PyObject *
12574ScandirIterator_iternext(ScandirIterator *iterator)
12575{
12576 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12577 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012578 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012579
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012580 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012581 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012582 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012583
12584 while (1) {
12585 if (!iterator->first_time) {
12586 Py_BEGIN_ALLOW_THREADS
12587 success = FindNextFileW(iterator->handle, file_data);
12588 Py_END_ALLOW_THREADS
12589 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012590 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012591 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012592 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012593 break;
12594 }
12595 }
12596 iterator->first_time = 0;
12597
12598 /* Skip over . and .. */
12599 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012600 wcscmp(file_data->cFileName, L"..") != 0) {
12601 entry = DirEntry_from_find_data(&iterator->path, file_data);
12602 if (!entry)
12603 break;
12604 return entry;
12605 }
Victor Stinner6036e442015-03-08 01:58:04 +010012606
12607 /* Loop till we get a non-dot directory or finish iterating */
12608 }
12609
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012610 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012611 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012612 return NULL;
12613}
12614
12615#else /* POSIX */
12616
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012617static int
12618ScandirIterator_is_closed(ScandirIterator *iterator)
12619{
12620 return !iterator->dirp;
12621}
12622
Victor Stinner6036e442015-03-08 01:58:04 +010012623static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012624ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012625{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012626 DIR *dirp = iterator->dirp;
12627
12628 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012629 return;
12630
Victor Stinner6036e442015-03-08 01:58:04 +010012631 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012632 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012633#ifdef HAVE_FDOPENDIR
12634 if (iterator->path.fd != -1)
12635 rewinddir(dirp);
12636#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012637 closedir(dirp);
12638 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012639 return;
12640}
12641
12642static PyObject *
12643ScandirIterator_iternext(ScandirIterator *iterator)
12644{
12645 struct dirent *direntp;
12646 Py_ssize_t name_len;
12647 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012648 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012649
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012650 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012651 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012652 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012653
12654 while (1) {
12655 errno = 0;
12656 Py_BEGIN_ALLOW_THREADS
12657 direntp = readdir(iterator->dirp);
12658 Py_END_ALLOW_THREADS
12659
12660 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012661 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012662 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012663 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012664 break;
12665 }
12666
12667 /* Skip over . and .. */
12668 name_len = NAMLEN(direntp);
12669 is_dot = direntp->d_name[0] == '.' &&
12670 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12671 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012672 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012673 name_len, direntp->d_ino
12674#ifdef HAVE_DIRENT_D_TYPE
12675 , direntp->d_type
12676#endif
12677 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012678 if (!entry)
12679 break;
12680 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012681 }
12682
12683 /* Loop till we get a non-dot directory or finish iterating */
12684 }
12685
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012686 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012687 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012688 return NULL;
12689}
12690
12691#endif
12692
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012693static PyObject *
12694ScandirIterator_close(ScandirIterator *self, PyObject *args)
12695{
12696 ScandirIterator_closedir(self);
12697 Py_RETURN_NONE;
12698}
12699
12700static PyObject *
12701ScandirIterator_enter(PyObject *self, PyObject *args)
12702{
12703 Py_INCREF(self);
12704 return self;
12705}
12706
12707static PyObject *
12708ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12709{
12710 ScandirIterator_closedir(self);
12711 Py_RETURN_NONE;
12712}
12713
Victor Stinner6036e442015-03-08 01:58:04 +010012714static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012715ScandirIterator_finalize(ScandirIterator *iterator)
12716{
12717 PyObject *error_type, *error_value, *error_traceback;
12718
12719 /* Save the current exception, if any. */
12720 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12721
12722 if (!ScandirIterator_is_closed(iterator)) {
12723 ScandirIterator_closedir(iterator);
12724
12725 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12726 "unclosed scandir iterator %R", iterator)) {
12727 /* Spurious errors can appear at shutdown */
12728 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12729 PyErr_WriteUnraisable((PyObject *) iterator);
12730 }
12731 }
12732 }
12733
Victor Stinner7bfa4092016-03-23 00:43:54 +010012734 path_cleanup(&iterator->path);
12735
12736 /* Restore the saved exception. */
12737 PyErr_Restore(error_type, error_value, error_traceback);
12738}
12739
12740static void
Victor Stinner6036e442015-03-08 01:58:04 +010012741ScandirIterator_dealloc(ScandirIterator *iterator)
12742{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012743 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12744 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012745
Victor Stinner6036e442015-03-08 01:58:04 +010012746 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12747}
12748
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012749static PyMethodDef ScandirIterator_methods[] = {
12750 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12751 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12752 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12753 {NULL}
12754};
12755
Benjamin Peterson5646de42015-04-12 17:56:34 -040012756static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012757 PyVarObject_HEAD_INIT(NULL, 0)
12758 MODNAME ".ScandirIterator", /* tp_name */
12759 sizeof(ScandirIterator), /* tp_basicsize */
12760 0, /* tp_itemsize */
12761 /* methods */
12762 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12763 0, /* tp_print */
12764 0, /* tp_getattr */
12765 0, /* tp_setattr */
12766 0, /* tp_compare */
12767 0, /* tp_repr */
12768 0, /* tp_as_number */
12769 0, /* tp_as_sequence */
12770 0, /* tp_as_mapping */
12771 0, /* tp_hash */
12772 0, /* tp_call */
12773 0, /* tp_str */
12774 0, /* tp_getattro */
12775 0, /* tp_setattro */
12776 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012777 Py_TPFLAGS_DEFAULT
12778 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012779 0, /* tp_doc */
12780 0, /* tp_traverse */
12781 0, /* tp_clear */
12782 0, /* tp_richcompare */
12783 0, /* tp_weaklistoffset */
12784 PyObject_SelfIter, /* tp_iter */
12785 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012786 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012787 0, /* tp_members */
12788 0, /* tp_getset */
12789 0, /* tp_base */
12790 0, /* tp_dict */
12791 0, /* tp_descr_get */
12792 0, /* tp_descr_set */
12793 0, /* tp_dictoffset */
12794 0, /* tp_init */
12795 0, /* tp_alloc */
12796 0, /* tp_new */
12797 0, /* tp_free */
12798 0, /* tp_is_gc */
12799 0, /* tp_bases */
12800 0, /* tp_mro */
12801 0, /* tp_cache */
12802 0, /* tp_subclasses */
12803 0, /* tp_weaklist */
12804 0, /* tp_del */
12805 0, /* tp_version_tag */
12806 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012807};
12808
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012809/*[clinic input]
12810os.scandir
12811
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012812 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012813
12814Return an iterator of DirEntry objects for given path.
12815
BNMetricsb9427072018-11-02 15:20:19 +000012816path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012817is bytes, the names of yielded DirEntry objects will also be bytes; in
12818all other circumstances they will be str.
12819
12820If path is None, uses the path='.'.
12821[clinic start generated code]*/
12822
Victor Stinner6036e442015-03-08 01:58:04 +010012823static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012824os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012825/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012826{
12827 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012828#ifdef MS_WINDOWS
12829 wchar_t *path_strW;
12830#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012831 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012832#ifdef HAVE_FDOPENDIR
12833 int fd = -1;
12834#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012835#endif
12836
12837 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12838 if (!iterator)
12839 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012840
12841#ifdef MS_WINDOWS
12842 iterator->handle = INVALID_HANDLE_VALUE;
12843#else
12844 iterator->dirp = NULL;
12845#endif
12846
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012847 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012848 /* Move the ownership to iterator->path */
12849 path->object = NULL;
12850 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012851
12852#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012853 iterator->first_time = 1;
12854
12855 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12856 if (!path_strW)
12857 goto error;
12858
12859 Py_BEGIN_ALLOW_THREADS
12860 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12861 Py_END_ALLOW_THREADS
12862
12863 PyMem_Free(path_strW);
12864
12865 if (iterator->handle == INVALID_HANDLE_VALUE) {
12866 path_error(&iterator->path);
12867 goto error;
12868 }
12869#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012870 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012871#ifdef HAVE_FDOPENDIR
12872 if (path->fd != -1) {
12873 /* closedir() closes the FD, so we duplicate it */
12874 fd = _Py_dup(path->fd);
12875 if (fd == -1)
12876 goto error;
12877
12878 Py_BEGIN_ALLOW_THREADS
12879 iterator->dirp = fdopendir(fd);
12880 Py_END_ALLOW_THREADS
12881 }
12882 else
12883#endif
12884 {
12885 if (iterator->path.narrow)
12886 path_str = iterator->path.narrow;
12887 else
12888 path_str = ".";
12889
12890 Py_BEGIN_ALLOW_THREADS
12891 iterator->dirp = opendir(path_str);
12892 Py_END_ALLOW_THREADS
12893 }
Victor Stinner6036e442015-03-08 01:58:04 +010012894
12895 if (!iterator->dirp) {
12896 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012897#ifdef HAVE_FDOPENDIR
12898 if (fd != -1) {
12899 Py_BEGIN_ALLOW_THREADS
12900 close(fd);
12901 Py_END_ALLOW_THREADS
12902 }
12903#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012904 goto error;
12905 }
12906#endif
12907
12908 return (PyObject *)iterator;
12909
12910error:
12911 Py_DECREF(iterator);
12912 return NULL;
12913}
12914
Ethan Furman410ef8e2016-06-04 12:06:26 -070012915/*
12916 Return the file system path representation of the object.
12917
12918 If the object is str or bytes, then allow it to pass through with
12919 an incremented refcount. If the object defines __fspath__(), then
12920 return the result of that method. All other types raise a TypeError.
12921*/
12922PyObject *
12923PyOS_FSPath(PyObject *path)
12924{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012925 /* For error message reasons, this function is manually inlined in
12926 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012927 _Py_IDENTIFIER(__fspath__);
12928 PyObject *func = NULL;
12929 PyObject *path_repr = NULL;
12930
12931 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12932 Py_INCREF(path);
12933 return path;
12934 }
12935
12936 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12937 if (NULL == func) {
12938 return PyErr_Format(PyExc_TypeError,
12939 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012940 "not %.200s",
12941 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012942 }
12943
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012944 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012945 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012946 if (NULL == path_repr) {
12947 return NULL;
12948 }
12949
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012950 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12951 PyErr_Format(PyExc_TypeError,
12952 "expected %.200s.__fspath__() to return str or bytes, "
12953 "not %.200s", Py_TYPE(path)->tp_name,
12954 Py_TYPE(path_repr)->tp_name);
12955 Py_DECREF(path_repr);
12956 return NULL;
12957 }
12958
Ethan Furman410ef8e2016-06-04 12:06:26 -070012959 return path_repr;
12960}
12961
12962/*[clinic input]
12963os.fspath
12964
12965 path: object
12966
12967Return the file system path representation of the object.
12968
Brett Cannonb4f43e92016-06-09 14:32:08 -070012969If the object is str or bytes, then allow it to pass through as-is. If the
12970object defines __fspath__(), then return the result of that method. All other
12971types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012972[clinic start generated code]*/
12973
12974static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012975os_fspath_impl(PyObject *module, PyObject *path)
12976/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012977{
12978 return PyOS_FSPath(path);
12979}
Victor Stinner6036e442015-03-08 01:58:04 +010012980
Victor Stinner9b1f4742016-09-06 16:18:52 -070012981#ifdef HAVE_GETRANDOM_SYSCALL
12982/*[clinic input]
12983os.getrandom
12984
12985 size: Py_ssize_t
12986 flags: int=0
12987
12988Obtain a series of random bytes.
12989[clinic start generated code]*/
12990
12991static PyObject *
12992os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12993/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12994{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012995 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012996 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012997
12998 if (size < 0) {
12999 errno = EINVAL;
13000 return posix_error();
13001 }
13002
Victor Stinnerec2319c2016-09-20 23:00:59 +020013003 bytes = PyBytes_FromStringAndSize(NULL, size);
13004 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013005 PyErr_NoMemory();
13006 return NULL;
13007 }
13008
13009 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013010 n = syscall(SYS_getrandom,
13011 PyBytes_AS_STRING(bytes),
13012 PyBytes_GET_SIZE(bytes),
13013 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013014 if (n < 0 && errno == EINTR) {
13015 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013016 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013017 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013018
13019 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013020 continue;
13021 }
13022 break;
13023 }
13024
13025 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013026 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013027 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013028 }
13029
Victor Stinnerec2319c2016-09-20 23:00:59 +020013030 if (n != size) {
13031 _PyBytes_Resize(&bytes, n);
13032 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013033
13034 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013035
13036error:
13037 Py_DECREF(bytes);
13038 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013039}
13040#endif /* HAVE_GETRANDOM_SYSCALL */
13041
Larry Hastings31826802013-10-19 00:09:25 -070013042
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013043static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013044
13045 OS_STAT_METHODDEF
13046 OS_ACCESS_METHODDEF
13047 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013048 OS_CHDIR_METHODDEF
13049 OS_CHFLAGS_METHODDEF
13050 OS_CHMOD_METHODDEF
13051 OS_FCHMOD_METHODDEF
13052 OS_LCHMOD_METHODDEF
13053 OS_CHOWN_METHODDEF
13054 OS_FCHOWN_METHODDEF
13055 OS_LCHOWN_METHODDEF
13056 OS_LCHFLAGS_METHODDEF
13057 OS_CHROOT_METHODDEF
13058 OS_CTERMID_METHODDEF
13059 OS_GETCWD_METHODDEF
13060 OS_GETCWDB_METHODDEF
13061 OS_LINK_METHODDEF
13062 OS_LISTDIR_METHODDEF
13063 OS_LSTAT_METHODDEF
13064 OS_MKDIR_METHODDEF
13065 OS_NICE_METHODDEF
13066 OS_GETPRIORITY_METHODDEF
13067 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013068 OS_POSIX_SPAWN_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013069 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013070 OS_RENAME_METHODDEF
13071 OS_REPLACE_METHODDEF
13072 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013073 OS_SYMLINK_METHODDEF
13074 OS_SYSTEM_METHODDEF
13075 OS_UMASK_METHODDEF
13076 OS_UNAME_METHODDEF
13077 OS_UNLINK_METHODDEF
13078 OS_REMOVE_METHODDEF
13079 OS_UTIME_METHODDEF
13080 OS_TIMES_METHODDEF
13081 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013082 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013083 OS_EXECV_METHODDEF
13084 OS_EXECVE_METHODDEF
13085 OS_SPAWNV_METHODDEF
13086 OS_SPAWNVE_METHODDEF
13087 OS_FORK1_METHODDEF
13088 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013089 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013090 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13091 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13092 OS_SCHED_GETPARAM_METHODDEF
13093 OS_SCHED_GETSCHEDULER_METHODDEF
13094 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13095 OS_SCHED_SETPARAM_METHODDEF
13096 OS_SCHED_SETSCHEDULER_METHODDEF
13097 OS_SCHED_YIELD_METHODDEF
13098 OS_SCHED_SETAFFINITY_METHODDEF
13099 OS_SCHED_GETAFFINITY_METHODDEF
13100 OS_OPENPTY_METHODDEF
13101 OS_FORKPTY_METHODDEF
13102 OS_GETEGID_METHODDEF
13103 OS_GETEUID_METHODDEF
13104 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013105#ifdef HAVE_GETGROUPLIST
13106 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13107#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013108 OS_GETGROUPS_METHODDEF
13109 OS_GETPID_METHODDEF
13110 OS_GETPGRP_METHODDEF
13111 OS_GETPPID_METHODDEF
13112 OS_GETUID_METHODDEF
13113 OS_GETLOGIN_METHODDEF
13114 OS_KILL_METHODDEF
13115 OS_KILLPG_METHODDEF
13116 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013117#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013118 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013119#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013120 OS_SETUID_METHODDEF
13121 OS_SETEUID_METHODDEF
13122 OS_SETREUID_METHODDEF
13123 OS_SETGID_METHODDEF
13124 OS_SETEGID_METHODDEF
13125 OS_SETREGID_METHODDEF
13126 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013127#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013128 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013129#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013130 OS_GETPGID_METHODDEF
13131 OS_SETPGRP_METHODDEF
13132 OS_WAIT_METHODDEF
13133 OS_WAIT3_METHODDEF
13134 OS_WAIT4_METHODDEF
13135 OS_WAITID_METHODDEF
13136 OS_WAITPID_METHODDEF
13137 OS_GETSID_METHODDEF
13138 OS_SETSID_METHODDEF
13139 OS_SETPGID_METHODDEF
13140 OS_TCGETPGRP_METHODDEF
13141 OS_TCSETPGRP_METHODDEF
13142 OS_OPEN_METHODDEF
13143 OS_CLOSE_METHODDEF
13144 OS_CLOSERANGE_METHODDEF
13145 OS_DEVICE_ENCODING_METHODDEF
13146 OS_DUP_METHODDEF
13147 OS_DUP2_METHODDEF
13148 OS_LOCKF_METHODDEF
13149 OS_LSEEK_METHODDEF
13150 OS_READ_METHODDEF
13151 OS_READV_METHODDEF
13152 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013153 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013154 OS_WRITE_METHODDEF
13155 OS_WRITEV_METHODDEF
13156 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013157 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013158#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013159 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013160 posix_sendfile__doc__},
13161#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013162 OS_FSTAT_METHODDEF
13163 OS_ISATTY_METHODDEF
13164 OS_PIPE_METHODDEF
13165 OS_PIPE2_METHODDEF
13166 OS_MKFIFO_METHODDEF
13167 OS_MKNOD_METHODDEF
13168 OS_MAJOR_METHODDEF
13169 OS_MINOR_METHODDEF
13170 OS_MAKEDEV_METHODDEF
13171 OS_FTRUNCATE_METHODDEF
13172 OS_TRUNCATE_METHODDEF
13173 OS_POSIX_FALLOCATE_METHODDEF
13174 OS_POSIX_FADVISE_METHODDEF
13175 OS_PUTENV_METHODDEF
13176 OS_UNSETENV_METHODDEF
13177 OS_STRERROR_METHODDEF
13178 OS_FCHDIR_METHODDEF
13179 OS_FSYNC_METHODDEF
13180 OS_SYNC_METHODDEF
13181 OS_FDATASYNC_METHODDEF
13182 OS_WCOREDUMP_METHODDEF
13183 OS_WIFCONTINUED_METHODDEF
13184 OS_WIFSTOPPED_METHODDEF
13185 OS_WIFSIGNALED_METHODDEF
13186 OS_WIFEXITED_METHODDEF
13187 OS_WEXITSTATUS_METHODDEF
13188 OS_WTERMSIG_METHODDEF
13189 OS_WSTOPSIG_METHODDEF
13190 OS_FSTATVFS_METHODDEF
13191 OS_STATVFS_METHODDEF
13192 OS_CONFSTR_METHODDEF
13193 OS_SYSCONF_METHODDEF
13194 OS_FPATHCONF_METHODDEF
13195 OS_PATHCONF_METHODDEF
13196 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013197 OS__GETFULLPATHNAME_METHODDEF
13198 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013199 OS__GETDISKUSAGE_METHODDEF
13200 OS__GETFINALPATHNAME_METHODDEF
13201 OS__GETVOLUMEPATHNAME_METHODDEF
13202 OS_GETLOADAVG_METHODDEF
13203 OS_URANDOM_METHODDEF
13204 OS_SETRESUID_METHODDEF
13205 OS_SETRESGID_METHODDEF
13206 OS_GETRESUID_METHODDEF
13207 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013208
Larry Hastings2f936352014-08-05 14:04:04 +100013209 OS_GETXATTR_METHODDEF
13210 OS_SETXATTR_METHODDEF
13211 OS_REMOVEXATTR_METHODDEF
13212 OS_LISTXATTR_METHODDEF
13213
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013214#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13215 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13216#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013217 OS_CPU_COUNT_METHODDEF
13218 OS_GET_INHERITABLE_METHODDEF
13219 OS_SET_INHERITABLE_METHODDEF
13220 OS_GET_HANDLE_INHERITABLE_METHODDEF
13221 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013222#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013223 OS_GET_BLOCKING_METHODDEF
13224 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013225#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013226 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013227 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013228 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000013229 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013230};
13231
13232
Brian Curtin52173d42010-12-02 18:29:18 +000013233#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013234static int
Brian Curtin52173d42010-12-02 18:29:18 +000013235enable_symlink()
13236{
13237 HANDLE tok;
13238 TOKEN_PRIVILEGES tok_priv;
13239 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000013240
13241 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013242 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013243
13244 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013245 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013246
13247 tok_priv.PrivilegeCount = 1;
13248 tok_priv.Privileges[0].Luid = luid;
13249 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
13250
13251 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
13252 sizeof(TOKEN_PRIVILEGES),
13253 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013254 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013255
Brian Curtin3b4499c2010-12-28 14:31:47 +000013256 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
13257 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000013258}
13259#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
13260
Barry Warsaw4a342091996-12-19 23:50:02 +000013261static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013262all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013263{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013264#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013265 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013266#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013267#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013268 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013269#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013270#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013271 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013272#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013273#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013274 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013275#endif
Fred Drakec9680921999-12-13 16:37:25 +000013276#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013277 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013278#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013279#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013280 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013281#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013282#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013283 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013284#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013285#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013286 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013287#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013288#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013289 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013290#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013291#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013292 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013293#endif
13294#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013295 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013296#endif
13297#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013298 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013299#endif
13300#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013301 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013302#endif
13303#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013304 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013305#endif
13306#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013307 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013308#endif
13309#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013310 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013311#endif
13312#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013313 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013314#endif
13315#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013316 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013317#endif
13318#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013319 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013320#endif
13321#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013322 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013323#endif
13324#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013325 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013326#endif
13327#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013328 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013329#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013330#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013331 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013332#endif
13333#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013334 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013335#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013336#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013337 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013338#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013339#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013340 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013341#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013342#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013343#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013344 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013345#endif
13346#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013347 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013348#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013349#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013350#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013351 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013352#endif
13353#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013354 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013355#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013356#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013357 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013358#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013359#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013360 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013361#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013362#ifdef O_TMPFILE
13363 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13364#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013365#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013366 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013367#endif
13368#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013369 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013370#endif
13371#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013372 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013373#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013374#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013375 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013376#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013377#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013378 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013379#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013380
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013381
Jesus Cea94363612012-06-22 18:32:07 +020013382#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013383 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013384#endif
13385#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013386 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013387#endif
13388
Tim Peters5aa91602002-01-30 05:46:57 +000013389/* MS Windows */
13390#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013391 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013392 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013393#endif
13394#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013395 /* Optimize for short life (keep in memory). */
13396 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013397 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013398#endif
13399#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013400 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013401 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013402#endif
13403#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013404 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013405 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013406#endif
13407#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013408 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013409 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013410#endif
13411
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013412/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013413#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013414 /* Send a SIGIO signal whenever input or output
13415 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013416 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013417#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013418#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013419 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013420 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013421#endif
13422#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013423 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013424 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013425#endif
13426#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013427 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013428 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013429#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013430#ifdef O_NOLINKS
13431 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013432 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013433#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013434#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013435 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013436 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013437#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013438
Victor Stinner8c62be82010-05-06 00:08:46 +000013439 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013440#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013441 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013442#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013443#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013444 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013445#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013446#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013447 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013448#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013449#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013450 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013451#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013452#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013453 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013454#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013455#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013456 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013457#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013458#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013459 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013460#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013461#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013462 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013463#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013464#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013465 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013466#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013467#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013468 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013469#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013470#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013471 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013472#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013473#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013474 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013475#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013476#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013477 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013478#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013479#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013480 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013481#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013482#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013483 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013484#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013485#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013486 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013487#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013488#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013489 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013490#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013491
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013492 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013493#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013494 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013495#endif /* ST_RDONLY */
13496#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013497 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013498#endif /* ST_NOSUID */
13499
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013500 /* GNU extensions */
13501#ifdef ST_NODEV
13502 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13503#endif /* ST_NODEV */
13504#ifdef ST_NOEXEC
13505 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13506#endif /* ST_NOEXEC */
13507#ifdef ST_SYNCHRONOUS
13508 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13509#endif /* ST_SYNCHRONOUS */
13510#ifdef ST_MANDLOCK
13511 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13512#endif /* ST_MANDLOCK */
13513#ifdef ST_WRITE
13514 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13515#endif /* ST_WRITE */
13516#ifdef ST_APPEND
13517 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13518#endif /* ST_APPEND */
13519#ifdef ST_NOATIME
13520 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13521#endif /* ST_NOATIME */
13522#ifdef ST_NODIRATIME
13523 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13524#endif /* ST_NODIRATIME */
13525#ifdef ST_RELATIME
13526 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13527#endif /* ST_RELATIME */
13528
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013529 /* FreeBSD sendfile() constants */
13530#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013531 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013532#endif
13533#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013534 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013535#endif
13536#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013537 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013538#endif
13539
Ross Lagerwall7807c352011-03-17 20:20:30 +020013540 /* constants for posix_fadvise */
13541#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013542 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013543#endif
13544#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013545 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013546#endif
13547#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013548 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013549#endif
13550#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013551 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013552#endif
13553#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013554 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013555#endif
13556#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013557 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013558#endif
13559
13560 /* constants for waitid */
13561#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013562 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13563 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13564 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013565#endif
13566#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013567 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013568#endif
13569#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013570 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013571#endif
13572#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013573 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013574#endif
13575#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013576 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013577#endif
13578#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013579 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013580#endif
13581#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013582 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013583#endif
13584#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013585 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013586#endif
13587
13588 /* constants for lockf */
13589#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013590 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013591#endif
13592#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013593 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013594#endif
13595#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013596 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013597#endif
13598#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013599 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013600#endif
13601
Pablo Galindo4defba32018-01-27 16:16:37 +000013602#ifdef RWF_DSYNC
13603 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13604#endif
13605#ifdef RWF_HIPRI
13606 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13607#endif
13608#ifdef RWF_SYNC
13609 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13610#endif
13611#ifdef RWF_NOWAIT
13612 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13613#endif
13614
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013615/* constants for posix_spawn */
13616#ifdef HAVE_POSIX_SPAWN
13617 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13618 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13619 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13620#endif
13621
Guido van Rossum246bc171999-02-01 23:54:31 +000013622#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013623 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13624 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13625 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13626 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13627 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013628#endif
13629
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013630#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013631#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013632 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013633#endif
13634#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013635 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013636#endif
13637#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013638 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013639#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013640#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013641 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013642#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013643#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013644 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013645#endif
13646#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013647 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013648#endif
13649#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013650 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013651#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013652#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013653 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013654#endif
13655#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013656 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013657#endif
13658#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013659 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013660#endif
13661#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013662 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013663#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013664#endif
13665
Benjamin Peterson9428d532011-09-14 11:45:52 -040013666#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013667 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13668 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13669 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013670#endif
13671
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013672#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013673 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013674#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013675#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013676 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013677#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013678#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013679 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013680#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013681#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013682 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013683#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013684#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013685 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013686#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013687#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013688 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013689#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013690#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013691 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013692#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013693#if HAVE_DECL_RTLD_MEMBER
13694 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13695#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013696
Victor Stinner9b1f4742016-09-06 16:18:52 -070013697#ifdef HAVE_GETRANDOM_SYSCALL
13698 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13699 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13700#endif
13701
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013702#if defined(__APPLE__)
13703 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13704#endif
13705
Victor Stinner8c62be82010-05-06 00:08:46 +000013706 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013707}
13708
13709
Martin v. Löwis1a214512008-06-11 05:26:20 +000013710static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013711 PyModuleDef_HEAD_INIT,
13712 MODNAME,
13713 posix__doc__,
13714 -1,
13715 posix_methods,
13716 NULL,
13717 NULL,
13718 NULL,
13719 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013720};
13721
13722
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013723static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013724
13725#ifdef HAVE_FACCESSAT
13726 "HAVE_FACCESSAT",
13727#endif
13728
13729#ifdef HAVE_FCHDIR
13730 "HAVE_FCHDIR",
13731#endif
13732
13733#ifdef HAVE_FCHMOD
13734 "HAVE_FCHMOD",
13735#endif
13736
13737#ifdef HAVE_FCHMODAT
13738 "HAVE_FCHMODAT",
13739#endif
13740
13741#ifdef HAVE_FCHOWN
13742 "HAVE_FCHOWN",
13743#endif
13744
Larry Hastings00964ed2013-08-12 13:49:30 -040013745#ifdef HAVE_FCHOWNAT
13746 "HAVE_FCHOWNAT",
13747#endif
13748
Larry Hastings9cf065c2012-06-22 16:30:09 -070013749#ifdef HAVE_FEXECVE
13750 "HAVE_FEXECVE",
13751#endif
13752
13753#ifdef HAVE_FDOPENDIR
13754 "HAVE_FDOPENDIR",
13755#endif
13756
Georg Brandl306336b2012-06-24 12:55:33 +020013757#ifdef HAVE_FPATHCONF
13758 "HAVE_FPATHCONF",
13759#endif
13760
Larry Hastings9cf065c2012-06-22 16:30:09 -070013761#ifdef HAVE_FSTATAT
13762 "HAVE_FSTATAT",
13763#endif
13764
13765#ifdef HAVE_FSTATVFS
13766 "HAVE_FSTATVFS",
13767#endif
13768
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013769#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013770 "HAVE_FTRUNCATE",
13771#endif
13772
Larry Hastings9cf065c2012-06-22 16:30:09 -070013773#ifdef HAVE_FUTIMENS
13774 "HAVE_FUTIMENS",
13775#endif
13776
13777#ifdef HAVE_FUTIMES
13778 "HAVE_FUTIMES",
13779#endif
13780
13781#ifdef HAVE_FUTIMESAT
13782 "HAVE_FUTIMESAT",
13783#endif
13784
13785#ifdef HAVE_LINKAT
13786 "HAVE_LINKAT",
13787#endif
13788
13789#ifdef HAVE_LCHFLAGS
13790 "HAVE_LCHFLAGS",
13791#endif
13792
13793#ifdef HAVE_LCHMOD
13794 "HAVE_LCHMOD",
13795#endif
13796
13797#ifdef HAVE_LCHOWN
13798 "HAVE_LCHOWN",
13799#endif
13800
13801#ifdef HAVE_LSTAT
13802 "HAVE_LSTAT",
13803#endif
13804
13805#ifdef HAVE_LUTIMES
13806 "HAVE_LUTIMES",
13807#endif
13808
13809#ifdef HAVE_MKDIRAT
13810 "HAVE_MKDIRAT",
13811#endif
13812
13813#ifdef HAVE_MKFIFOAT
13814 "HAVE_MKFIFOAT",
13815#endif
13816
13817#ifdef HAVE_MKNODAT
13818 "HAVE_MKNODAT",
13819#endif
13820
13821#ifdef HAVE_OPENAT
13822 "HAVE_OPENAT",
13823#endif
13824
13825#ifdef HAVE_READLINKAT
13826 "HAVE_READLINKAT",
13827#endif
13828
13829#ifdef HAVE_RENAMEAT
13830 "HAVE_RENAMEAT",
13831#endif
13832
13833#ifdef HAVE_SYMLINKAT
13834 "HAVE_SYMLINKAT",
13835#endif
13836
13837#ifdef HAVE_UNLINKAT
13838 "HAVE_UNLINKAT",
13839#endif
13840
13841#ifdef HAVE_UTIMENSAT
13842 "HAVE_UTIMENSAT",
13843#endif
13844
13845#ifdef MS_WINDOWS
13846 "MS_WINDOWS",
13847#endif
13848
13849 NULL
13850};
13851
13852
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013853PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013854INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013855{
Victor Stinner8c62be82010-05-06 00:08:46 +000013856 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013857 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013858 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013859
Brian Curtin52173d42010-12-02 18:29:18 +000013860#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013861 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013862#endif
13863
Victor Stinner8c62be82010-05-06 00:08:46 +000013864 m = PyModule_Create(&posixmodule);
13865 if (m == NULL)
13866 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013867
Victor Stinner8c62be82010-05-06 00:08:46 +000013868 /* Initialize environ dictionary */
13869 v = convertenviron();
13870 Py_XINCREF(v);
13871 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13872 return NULL;
13873 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013874
Victor Stinner8c62be82010-05-06 00:08:46 +000013875 if (all_ins(m))
13876 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013877
Victor Stinner8c62be82010-05-06 00:08:46 +000013878 if (setup_confname_tables(m))
13879 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013880
Victor Stinner8c62be82010-05-06 00:08:46 +000013881 Py_INCREF(PyExc_OSError);
13882 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013883
Guido van Rossumb3d39562000-01-31 18:41:26 +000013884#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013885 if (posix_putenv_garbage == NULL)
13886 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013887#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013888
Victor Stinner8c62be82010-05-06 00:08:46 +000013889 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013890#if defined(HAVE_WAITID) && !defined(__APPLE__)
13891 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013892 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
13893 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013894 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013895 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013896#endif
13897
Christian Heimes25827622013-10-12 01:27:08 +020013898 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013899 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13900 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13901 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013902 StatResultType = PyStructSequence_NewType(&stat_result_desc);
13903 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013904 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013905 }
13906 structseq_new = StatResultType->tp_new;
13907 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013908
Christian Heimes25827622013-10-12 01:27:08 +020013909 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013910 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
13911 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013912 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013913 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013914#ifdef NEED_TICKS_PER_SECOND
13915# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013916 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013917# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013918 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013919# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013920 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013921# endif
13922#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013923
William Orr81574b82018-10-01 22:19:56 -070013924#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013925 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013926 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
13927 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013928 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013929 }
13930 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013931#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013932
13933 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013934 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
13935 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013936 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013937 }
Victor Stinner6036e442015-03-08 01:58:04 +010013938
13939 /* initialize scandir types */
13940 if (PyType_Ready(&ScandirIteratorType) < 0)
13941 return NULL;
13942 if (PyType_Ready(&DirEntryType) < 0)
13943 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013944 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013945#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013946 Py_INCREF((PyObject*) WaitidResultType);
13947 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020013948#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013949 Py_INCREF((PyObject*) StatResultType);
13950 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
13951 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000013952 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013953 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013954
13955#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013956 Py_INCREF(SchedParamType);
13957 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013958#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013959
Larry Hastings605a62d2012-06-24 04:33:36 -070013960 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013961 TimesResultType = PyStructSequence_NewType(&times_result_desc);
13962 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013963 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013964 }
13965 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070013966
13967 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013968 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
13969 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013970 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013971 }
13972 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070013973
Thomas Wouters477c8d52006-05-27 19:21:47 +000013974#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013975 /*
13976 * Step 2 of weak-linking support on Mac OS X.
13977 *
13978 * The code below removes functions that are not available on the
13979 * currently active platform.
13980 *
13981 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013982 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013983 * OSX 10.4.
13984 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013985#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013986 if (fstatvfs == NULL) {
13987 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13988 return NULL;
13989 }
13990 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013991#endif /* HAVE_FSTATVFS */
13992
13993#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013994 if (statvfs == NULL) {
13995 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13996 return NULL;
13997 }
13998 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013999#endif /* HAVE_STATVFS */
14000
14001# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014002 if (lchown == NULL) {
14003 if (PyObject_DelAttrString(m, "lchown") == -1) {
14004 return NULL;
14005 }
14006 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014007#endif /* HAVE_LCHOWN */
14008
14009
14010#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014011
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014012 Py_INCREF(TerminalSizeType);
14013 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014014
Larry Hastings6fe20b32012-04-19 15:07:49 -070014015 billion = PyLong_FromLong(1000000000);
14016 if (!billion)
14017 return NULL;
14018
Larry Hastings9cf065c2012-06-22 16:30:09 -070014019 /* suppress "function not used" warnings */
14020 {
14021 int ignored;
14022 fd_specified("", -1);
14023 follow_symlinks_specified("", 1);
14024 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14025 dir_fd_converter(Py_None, &ignored);
14026 dir_fd_unavailable(Py_None, &ignored);
14027 }
14028
14029 /*
14030 * provide list of locally available functions
14031 * so os.py can populate support_* lists
14032 */
14033 list = PyList_New(0);
14034 if (!list)
14035 return NULL;
14036 for (trace = have_functions; *trace; trace++) {
14037 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14038 if (!unicode)
14039 return NULL;
14040 if (PyList_Append(list, unicode))
14041 return NULL;
14042 Py_DECREF(unicode);
14043 }
14044 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014045
14046 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014047 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014048
14049 initialized = 1;
14050
Victor Stinner8c62be82010-05-06 00:08:46 +000014051 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014052}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014053
14054#ifdef __cplusplus
14055}
14056#endif