blob: 4ff1694c58339aeba163e1f7bfc11461374d1279 [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]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002650os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002651
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
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002661os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002662/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
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);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002667 if (ret == NULL) {
2668 return posix_error();
2669 }
2670 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002671}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002672#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002673
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002674#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002675/*[clinic input]
2676os.ctermid
2677
2678Return the name of the controlling terminal for this process.
2679[clinic start generated code]*/
2680
Larry Hastings2f936352014-08-05 14:04:04 +10002681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002682os_ctermid_impl(PyObject *module)
2683/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684{
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 char *ret;
2686 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002687
Greg Wardb48bc172000-03-01 21:51:56 +00002688#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002689 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002690#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002691 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002692#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002693 if (ret == NULL)
2694 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002695 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002696}
Larry Hastings2f936352014-08-05 14:04:04 +10002697#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002698
Larry Hastings2f936352014-08-05 14:04:04 +10002699
2700/*[clinic input]
2701os.chdir
2702
2703 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2704
2705Change the current working directory to the specified path.
2706
2707path may always be specified as a string.
2708On some platforms, path may also be specified as an open file descriptor.
2709 If this functionality is unavailable, using it raises an exception.
2710[clinic start generated code]*/
2711
Larry Hastings2f936352014-08-05 14:04:04 +10002712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002713os_chdir_impl(PyObject *module, path_t *path)
2714/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002715{
2716 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717
2718 Py_BEGIN_ALLOW_THREADS
2719#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002720 /* on unix, success = 0, on windows, success = !0 */
2721 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002722#else
2723#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002724 if (path->fd != -1)
2725 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726 else
2727#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002728 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729#endif
2730 Py_END_ALLOW_THREADS
2731
2732 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002733 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002734 }
2735
Larry Hastings2f936352014-08-05 14:04:04 +10002736 Py_RETURN_NONE;
2737}
2738
2739
2740#ifdef HAVE_FCHDIR
2741/*[clinic input]
2742os.fchdir
2743
2744 fd: fildes
2745
2746Change to the directory of the given file descriptor.
2747
2748fd must be opened on a directory, not a file.
2749Equivalent to os.chdir(fd).
2750
2751[clinic start generated code]*/
2752
Fred Drake4d1e64b2002-04-15 19:40:07 +00002753static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002754os_fchdir_impl(PyObject *module, int fd)
2755/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002756{
Larry Hastings2f936352014-08-05 14:04:04 +10002757 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002758}
2759#endif /* HAVE_FCHDIR */
2760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002761
Larry Hastings2f936352014-08-05 14:04:04 +10002762/*[clinic input]
2763os.chmod
2764
2765 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002766 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002767 On some platforms, path may also be specified as an open file descriptor.
2768 If this functionality is unavailable, using it raises an exception.
2769
2770 mode: int
2771 Operating-system mode bitfield.
2772
2773 *
2774
2775 dir_fd : dir_fd(requires='fchmodat') = None
2776 If not None, it should be a file descriptor open to a directory,
2777 and path should be relative; path will then be relative to that
2778 directory.
2779
2780 follow_symlinks: bool = True
2781 If False, and the last element of the path is a symbolic link,
2782 chmod will modify the symbolic link itself instead of the file
2783 the link points to.
2784
2785Change the access permissions of a file.
2786
2787It is an error to use dir_fd or follow_symlinks when specifying path as
2788 an open file descriptor.
2789dir_fd and follow_symlinks may not be implemented on your platform.
2790 If they are unavailable, using them will raise a NotImplementedError.
2791
2792[clinic start generated code]*/
2793
Larry Hastings2f936352014-08-05 14:04:04 +10002794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002795os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002796 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002797/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002798{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002801#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002802 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002804
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805#ifdef HAVE_FCHMODAT
2806 int fchmodat_nofollow_unsupported = 0;
2807#endif
2808
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2810 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002811 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812#endif
2813
2814#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002815 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002816 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002817 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818 result = 0;
2819 else {
2820 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 attr &= ~FILE_ATTRIBUTE_READONLY;
2822 else
2823 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002824 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 }
2826 Py_END_ALLOW_THREADS
2827
2828 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002829 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830 }
2831#else /* MS_WINDOWS */
2832 Py_BEGIN_ALLOW_THREADS
2833#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002834 if (path->fd != -1)
2835 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836 else
2837#endif
2838#ifdef HAVE_LCHMOD
2839 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002840 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841 else
2842#endif
2843#ifdef HAVE_FCHMODAT
2844 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2845 /*
2846 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2847 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002848 * and then says it isn't implemented yet.
2849 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850 *
2851 * Once it is supported, os.chmod will automatically
2852 * support dir_fd and follow_symlinks=False. (Hopefully.)
2853 * Until then, we need to be careful what exception we raise.
2854 */
Larry Hastings2f936352014-08-05 14:04:04 +10002855 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002856 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2857 /*
2858 * But wait! We can't throw the exception without allowing threads,
2859 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2860 */
2861 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002862 result &&
2863 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2864 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002865 }
2866 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002867#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002868 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869 Py_END_ALLOW_THREADS
2870
2871 if (result) {
2872#ifdef HAVE_FCHMODAT
2873 if (fchmodat_nofollow_unsupported) {
2874 if (dir_fd != DEFAULT_DIR_FD)
2875 dir_fd_and_follow_symlinks_invalid("chmod",
2876 dir_fd, follow_symlinks);
2877 else
2878 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002879 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880 }
2881 else
2882#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002883 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884 }
2885#endif
2886
Larry Hastings2f936352014-08-05 14:04:04 +10002887 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002888}
2889
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890
Christian Heimes4e30a842007-11-30 22:12:06 +00002891#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002892/*[clinic input]
2893os.fchmod
2894
2895 fd: int
2896 mode: int
2897
2898Change the access permissions of the file given by file descriptor fd.
2899
2900Equivalent to os.chmod(fd, mode).
2901[clinic start generated code]*/
2902
Larry Hastings2f936352014-08-05 14:04:04 +10002903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002904os_fchmod_impl(PyObject *module, int fd, int mode)
2905/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002906{
2907 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002908 int async_err = 0;
2909
2910 do {
2911 Py_BEGIN_ALLOW_THREADS
2912 res = fchmod(fd, mode);
2913 Py_END_ALLOW_THREADS
2914 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2915 if (res != 0)
2916 return (!async_err) ? posix_error() : NULL;
2917
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002919}
2920#endif /* HAVE_FCHMOD */
2921
Larry Hastings2f936352014-08-05 14:04:04 +10002922
Christian Heimes4e30a842007-11-30 22:12:06 +00002923#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002924/*[clinic input]
2925os.lchmod
2926
2927 path: path_t
2928 mode: int
2929
2930Change the access permissions of a file, without following symbolic links.
2931
2932If path is a symlink, this affects the link itself rather than the target.
2933Equivalent to chmod(path, mode, follow_symlinks=False)."
2934[clinic start generated code]*/
2935
Larry Hastings2f936352014-08-05 14:04:04 +10002936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002937os_lchmod_impl(PyObject *module, path_t *path, int mode)
2938/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002939{
Victor Stinner8c62be82010-05-06 00:08:46 +00002940 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002942 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002944 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002945 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002946 return NULL;
2947 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002949}
2950#endif /* HAVE_LCHMOD */
2951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002952
Thomas Wouterscf297e42007-02-23 15:07:44 +00002953#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002954/*[clinic input]
2955os.chflags
2956
2957 path: path_t
2958 flags: unsigned_long(bitwise=True)
2959 follow_symlinks: bool=True
2960
2961Set file flags.
2962
2963If follow_symlinks is False, and the last element of the path is a symbolic
2964 link, chflags will change flags on the symbolic link itself instead of the
2965 file the link points to.
2966follow_symlinks may not be implemented on your platform. If it is
2967unavailable, using it will raise a NotImplementedError.
2968
2969[clinic start generated code]*/
2970
Larry Hastings2f936352014-08-05 14:04:04 +10002971static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002972os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002973 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002974/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002975{
2976 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977
2978#ifndef HAVE_LCHFLAGS
2979 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002980 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002981#endif
2982
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984#ifdef HAVE_LCHFLAGS
2985 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002986 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987 else
2988#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002989 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002990 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002991
Larry Hastings2f936352014-08-05 14:04:04 +10002992 if (result)
2993 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
Larry Hastings2f936352014-08-05 14:04:04 +10002995 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002996}
2997#endif /* HAVE_CHFLAGS */
2998
Larry Hastings2f936352014-08-05 14:04:04 +10002999
Thomas Wouterscf297e42007-02-23 15:07:44 +00003000#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003001/*[clinic input]
3002os.lchflags
3003
3004 path: path_t
3005 flags: unsigned_long(bitwise=True)
3006
3007Set file flags.
3008
3009This function will not follow symbolic links.
3010Equivalent to chflags(path, flags, follow_symlinks=False).
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3015/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003019 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003021 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003022 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003023 }
Victor Stinner292c8352012-10-30 02:17:38 +01003024 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003025}
3026#endif /* HAVE_LCHFLAGS */
3027
Larry Hastings2f936352014-08-05 14:04:04 +10003028
Martin v. Löwis244edc82001-10-04 22:44:26 +00003029#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003030/*[clinic input]
3031os.chroot
3032 path: path_t
3033
3034Change root directory to path.
3035
3036[clinic start generated code]*/
3037
Larry Hastings2f936352014-08-05 14:04:04 +10003038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003039os_chroot_impl(PyObject *module, path_t *path)
3040/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003041{
3042 int res;
3043 Py_BEGIN_ALLOW_THREADS
3044 res = chroot(path->narrow);
3045 Py_END_ALLOW_THREADS
3046 if (res < 0)
3047 return path_error(path);
3048 Py_RETURN_NONE;
3049}
3050#endif /* HAVE_CHROOT */
3051
Martin v. Löwis244edc82001-10-04 22:44:26 +00003052
Guido van Rossum21142a01999-01-08 21:05:37 +00003053#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003054/*[clinic input]
3055os.fsync
3056
3057 fd: fildes
3058
3059Force write of fd to disk.
3060[clinic start generated code]*/
3061
Larry Hastings2f936352014-08-05 14:04:04 +10003062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003063os_fsync_impl(PyObject *module, int fd)
3064/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003065{
3066 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003067}
3068#endif /* HAVE_FSYNC */
3069
Larry Hastings2f936352014-08-05 14:04:04 +10003070
Ross Lagerwall7807c352011-03-17 20:20:30 +02003071#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003072/*[clinic input]
3073os.sync
3074
3075Force write of everything to disk.
3076[clinic start generated code]*/
3077
Larry Hastings2f936352014-08-05 14:04:04 +10003078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003079os_sync_impl(PyObject *module)
3080/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003081{
3082 Py_BEGIN_ALLOW_THREADS
3083 sync();
3084 Py_END_ALLOW_THREADS
3085 Py_RETURN_NONE;
3086}
Larry Hastings2f936352014-08-05 14:04:04 +10003087#endif /* HAVE_SYNC */
3088
Ross Lagerwall7807c352011-03-17 20:20:30 +02003089
Guido van Rossum21142a01999-01-08 21:05:37 +00003090#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003091#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003092extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3093#endif
3094
Larry Hastings2f936352014-08-05 14:04:04 +10003095/*[clinic input]
3096os.fdatasync
3097
3098 fd: fildes
3099
3100Force write of fd to disk without forcing update of metadata.
3101[clinic start generated code]*/
3102
Larry Hastings2f936352014-08-05 14:04:04 +10003103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003104os_fdatasync_impl(PyObject *module, int fd)
3105/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003106{
3107 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003108}
3109#endif /* HAVE_FDATASYNC */
3110
3111
Fredrik Lundh10723342000-07-10 16:38:09 +00003112#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003113/*[clinic input]
3114os.chown
3115
3116 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003117 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003118
3119 uid: uid_t
3120
3121 gid: gid_t
3122
3123 *
3124
3125 dir_fd : dir_fd(requires='fchownat') = None
3126 If not None, it should be a file descriptor open to a directory,
3127 and path should be relative; path will then be relative to that
3128 directory.
3129
3130 follow_symlinks: bool = True
3131 If False, and the last element of the path is a symbolic link,
3132 stat will examine the symbolic link itself instead of the file
3133 the link points to.
3134
3135Change the owner and group id of path to the numeric uid and gid.\
3136
3137path may always be specified as a string.
3138On some platforms, path may also be specified as an open file descriptor.
3139 If this functionality is unavailable, using it raises an exception.
3140If dir_fd is not None, it should be a file descriptor open to a directory,
3141 and path should be relative; path will then be relative to that directory.
3142If follow_symlinks is False, and the last element of the path is a symbolic
3143 link, chown will modify the symbolic link itself instead of the file the
3144 link points to.
3145It is an error to use dir_fd or follow_symlinks when specifying path as
3146 an open file descriptor.
3147dir_fd and follow_symlinks may not be implemented on your platform.
3148 If they are unavailable, using them will raise a NotImplementedError.
3149
3150[clinic start generated code]*/
3151
Larry Hastings2f936352014-08-05 14:04:04 +10003152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003153os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003154 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003155/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003156{
3157 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003158
3159#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3160 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003161 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003163 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3164 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3165 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003166
3167#ifdef __APPLE__
3168 /*
3169 * This is for Mac OS X 10.3, which doesn't have lchown.
3170 * (But we still have an lchown symbol because of weak-linking.)
3171 * It doesn't have fchownat either. So there's no possibility
3172 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003173 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 if ((!follow_symlinks) && (lchown == NULL)) {
3175 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003176 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177 }
3178#endif
3179
Victor Stinner8c62be82010-05-06 00:08:46 +00003180 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003182 if (path->fd != -1)
3183 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184 else
3185#endif
3186#ifdef HAVE_LCHOWN
3187 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003188 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189 else
3190#endif
3191#ifdef HAVE_FCHOWNAT
3192 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003193 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3195 else
3196#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003197 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199
Larry Hastings2f936352014-08-05 14:04:04 +10003200 if (result)
3201 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202
Larry Hastings2f936352014-08-05 14:04:04 +10003203 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003204}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003205#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003206
Larry Hastings2f936352014-08-05 14:04:04 +10003207
Christian Heimes4e30a842007-11-30 22:12:06 +00003208#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003209/*[clinic input]
3210os.fchown
3211
3212 fd: int
3213 uid: uid_t
3214 gid: gid_t
3215
3216Change the owner and group id of the file specified by file descriptor.
3217
3218Equivalent to os.chown(fd, uid, gid).
3219
3220[clinic start generated code]*/
3221
Larry Hastings2f936352014-08-05 14:04:04 +10003222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003223os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3224/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003225{
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003227 int async_err = 0;
3228
3229 do {
3230 Py_BEGIN_ALLOW_THREADS
3231 res = fchown(fd, uid, gid);
3232 Py_END_ALLOW_THREADS
3233 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3234 if (res != 0)
3235 return (!async_err) ? posix_error() : NULL;
3236
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003238}
3239#endif /* HAVE_FCHOWN */
3240
Larry Hastings2f936352014-08-05 14:04:04 +10003241
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003242#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003243/*[clinic input]
3244os.lchown
3245
3246 path : path_t
3247 uid: uid_t
3248 gid: gid_t
3249
3250Change the owner and group id of path to the numeric uid and gid.
3251
3252This function will not follow symbolic links.
3253Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3254[clinic start generated code]*/
3255
Larry Hastings2f936352014-08-05 14:04:04 +10003256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003257os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3258/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003259{
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003262 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003264 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003265 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003266 }
Larry Hastings2f936352014-08-05 14:04:04 +10003267 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003268}
3269#endif /* HAVE_LCHOWN */
3270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003271
Barry Warsaw53699e91996-12-10 23:23:01 +00003272static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003273posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003274{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003275 char *buf, *tmpbuf;
3276 char *cwd;
3277 const size_t chunk = 1024;
3278 size_t buflen = 0;
3279 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003280
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003281#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003283 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 wchar_t *wbuf2 = wbuf;
3285 PyObject *resobj;
3286 DWORD len;
3287 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003288 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 /* If the buffer is large enough, len does not include the
3290 terminating \0. If the buffer is too small, len includes
3291 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003292 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003293 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 if (wbuf2)
3295 len = GetCurrentDirectoryW(len, wbuf2);
3296 }
3297 Py_END_ALLOW_THREADS
3298 if (!wbuf2) {
3299 PyErr_NoMemory();
3300 return NULL;
3301 }
3302 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003303 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003304 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003305 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003306 }
3307 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003308 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003309 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 return resobj;
3311 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003312
3313 if (win32_warn_bytes_api())
3314 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003315#endif
3316
Victor Stinner4403d7d2015-04-25 00:16:10 +02003317 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003319 do {
3320 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003321#ifdef MS_WINDOWS
3322 if (buflen > INT_MAX) {
3323 PyErr_NoMemory();
3324 break;
3325 }
3326#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003327 tmpbuf = PyMem_RawRealloc(buf, buflen);
3328 if (tmpbuf == NULL)
3329 break;
3330
3331 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003332#ifdef MS_WINDOWS
3333 cwd = getcwd(buf, (int)buflen);
3334#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003335 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003336#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003337 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003339
3340 if (cwd == NULL) {
3341 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003342 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003343 }
3344
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003346 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3347 else
3348 obj = PyUnicode_DecodeFSDefault(buf);
3349 PyMem_RawFree(buf);
3350
3351 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003352}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003353
Larry Hastings2f936352014-08-05 14:04:04 +10003354
3355/*[clinic input]
3356os.getcwd
3357
3358Return a unicode string representing the current working directory.
3359[clinic start generated code]*/
3360
Larry Hastings2f936352014-08-05 14:04:04 +10003361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003362os_getcwd_impl(PyObject *module)
3363/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003364{
3365 return posix_getcwd(0);
3366}
3367
Larry Hastings2f936352014-08-05 14:04:04 +10003368
3369/*[clinic input]
3370os.getcwdb
3371
3372Return a bytes string representing the current working directory.
3373[clinic start generated code]*/
3374
Larry Hastings2f936352014-08-05 14:04:04 +10003375static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003376os_getcwdb_impl(PyObject *module)
3377/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003378{
3379 return posix_getcwd(1);
3380}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003381
Larry Hastings2f936352014-08-05 14:04:04 +10003382
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3384#define HAVE_LINK 1
3385#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003386
Guido van Rossumb6775db1994-08-01 11:34:53 +00003387#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003388/*[clinic input]
3389
3390os.link
3391
3392 src : path_t
3393 dst : path_t
3394 *
3395 src_dir_fd : dir_fd = None
3396 dst_dir_fd : dir_fd = None
3397 follow_symlinks: bool = True
3398
3399Create a hard link to a file.
3400
3401If either src_dir_fd or dst_dir_fd is not None, it should be a file
3402 descriptor open to a directory, and the respective path string (src or dst)
3403 should be relative; the path will then be relative to that directory.
3404If follow_symlinks is False, and the last element of src is a symbolic
3405 link, link will create a link to the symbolic link itself instead of the
3406 file the link points to.
3407src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3408 platform. If they are unavailable, using them will raise a
3409 NotImplementedError.
3410[clinic start generated code]*/
3411
Larry Hastings2f936352014-08-05 14:04:04 +10003412static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003413os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003414 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003415/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003416{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003418 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419#else
3420 int result;
3421#endif
3422
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423#ifndef HAVE_LINKAT
3424 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3425 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003426 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 }
3428#endif
3429
Steve Dowercc16be82016-09-08 10:35:16 -07003430#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003431 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 PyErr_SetString(PyExc_NotImplementedError,
3433 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003434 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435 }
Steve Dowercc16be82016-09-08 10:35:16 -07003436#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003437
Brian Curtin1b9df392010-11-24 20:24:31 +00003438#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003440 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003442
Larry Hastings2f936352014-08-05 14:04:04 +10003443 if (!result)
3444 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445#else
3446 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003447#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3449 (dst_dir_fd != DEFAULT_DIR_FD) ||
3450 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003451 result = linkat(src_dir_fd, src->narrow,
3452 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3454 else
Steve Dowercc16be82016-09-08 10:35:16 -07003455#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003456 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003458
Larry Hastings2f936352014-08-05 14:04:04 +10003459 if (result)
3460 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003461#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462
Larry Hastings2f936352014-08-05 14:04:04 +10003463 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003464}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465#endif
3466
Brian Curtin1b9df392010-11-24 20:24:31 +00003467
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003468#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003469static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003470_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003471{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 PyObject *v;
3473 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3474 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003475 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003477 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479
Steve Dowercc16be82016-09-08 10:35:16 -07003480 WIN32_FIND_DATAW wFileData;
3481 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003482
Steve Dowercc16be82016-09-08 10:35:16 -07003483 if (!path->wide) { /* Default arg: "." */
3484 po_wchars = L".";
3485 len = 1;
3486 } else {
3487 po_wchars = path->wide;
3488 len = wcslen(path->wide);
3489 }
3490 /* The +5 is so we can append "\\*.*\0" */
3491 wnamebuf = PyMem_New(wchar_t, len + 5);
3492 if (!wnamebuf) {
3493 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 }
Steve Dowercc16be82016-09-08 10:35:16 -07003496 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003498 wchar_t wch = wnamebuf[len-1];
3499 if (wch != SEP && wch != ALTSEP && wch != L':')
3500 wnamebuf[len++] = SEP;
3501 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 }
Steve Dowercc16be82016-09-08 10:35:16 -07003503 if ((list = PyList_New(0)) == NULL) {
3504 goto exit;
3505 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003506 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003507 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003508 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 if (hFindFile == INVALID_HANDLE_VALUE) {
3510 int error = GetLastError();
3511 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 goto exit;
3513 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003514 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003515 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 }
3517 do {
3518 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003519 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3520 wcscmp(wFileData.cFileName, L"..") != 0) {
3521 v = PyUnicode_FromWideChar(wFileData.cFileName,
3522 wcslen(wFileData.cFileName));
3523 if (path->narrow && v) {
3524 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3525 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003526 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527 Py_DECREF(list);
3528 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 break;
3530 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 Py_DECREF(list);
3534 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 break;
3536 }
3537 Py_DECREF(v);
3538 }
3539 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003540 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 Py_END_ALLOW_THREADS
3542 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3543 it got to the end of the directory. */
3544 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003546 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 }
3549 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003550
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551exit:
3552 if (hFindFile != INVALID_HANDLE_VALUE) {
3553 if (FindClose(hFindFile) == FALSE) {
3554 if (list != NULL) {
3555 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003556 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 }
3558 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003560 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003561
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003563} /* end of _listdir_windows_no_opendir */
3564
3565#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3566
3567static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003568_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003569{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003570 PyObject *v;
3571 DIR *dirp = NULL;
3572 struct dirent *ep;
3573 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003574#ifdef HAVE_FDOPENDIR
3575 int fd = -1;
3576#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003577
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003580 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003582 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003583 if (fd == -1)
3584 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585
Larry Hastingsfdaea062012-06-25 04:42:23 -07003586 return_str = 1;
3587
Larry Hastings9cf065c2012-06-22 16:30:09 -07003588 Py_BEGIN_ALLOW_THREADS
3589 dirp = fdopendir(fd);
3590 Py_END_ALLOW_THREADS
3591 }
3592 else
3593#endif
3594 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003595 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003596 if (path->narrow) {
3597 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003598 /* only return bytes if they specified a bytes-like object */
3599 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003600 }
3601 else {
3602 name = ".";
3603 return_str = 1;
3604 }
3605
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_BEGIN_ALLOW_THREADS
3607 dirp = opendir(name);
3608 Py_END_ALLOW_THREADS
3609 }
3610
3611 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003612 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003613#ifdef HAVE_FDOPENDIR
3614 if (fd != -1) {
3615 Py_BEGIN_ALLOW_THREADS
3616 close(fd);
3617 Py_END_ALLOW_THREADS
3618 }
3619#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 goto exit;
3621 }
3622 if ((list = PyList_New(0)) == NULL) {
3623 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 }
3625 for (;;) {
3626 errno = 0;
3627 Py_BEGIN_ALLOW_THREADS
3628 ep = readdir(dirp);
3629 Py_END_ALLOW_THREADS
3630 if (ep == NULL) {
3631 if (errno == 0) {
3632 break;
3633 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003635 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 }
3638 }
3639 if (ep->d_name[0] == '.' &&
3640 (NAMLEN(ep) == 1 ||
3641 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3642 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003643 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003644 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3645 else
3646 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003648 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 break;
3650 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003651 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003652 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 break;
3655 }
3656 Py_DECREF(v);
3657 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003658
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659exit:
3660 if (dirp != NULL) {
3661 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003662#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 if (fd > -1)
3664 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003665#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666 closedir(dirp);
3667 Py_END_ALLOW_THREADS
3668 }
3669
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003671} /* end of _posix_listdir */
3672#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003673
Larry Hastings2f936352014-08-05 14:04:04 +10003674
3675/*[clinic input]
3676os.listdir
3677
3678 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3679
3680Return a list containing the names of the files in the directory.
3681
BNMetricsb9427072018-11-02 15:20:19 +00003682path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003683 the filenames returned will also be bytes; in all other circumstances
3684 the filenames returned will be str.
3685If path is None, uses the path='.'.
3686On some platforms, path may also be specified as an open file descriptor;\
3687 the file descriptor must refer to a directory.
3688 If this functionality is unavailable, using it raises NotImplementedError.
3689
3690The list is in arbitrary order. It does not include the special
3691entries '.' and '..' even if they are present in the directory.
3692
3693
3694[clinic start generated code]*/
3695
Larry Hastings2f936352014-08-05 14:04:04 +10003696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003697os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003698/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003699{
3700#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3701 return _listdir_windows_no_opendir(path, NULL);
3702#else
3703 return _posix_listdir(path, NULL);
3704#endif
3705}
3706
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003707#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003708/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003709/*[clinic input]
3710os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003711
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003712 path: path_t
3713 /
3714
3715[clinic start generated code]*/
3716
3717static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003718os__getfullpathname_impl(PyObject *module, path_t *path)
3719/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003720{
Steve Dowercc16be82016-09-08 10:35:16 -07003721 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3722 wchar_t *wtemp;
3723 DWORD result;
3724 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003725
Steve Dowercc16be82016-09-08 10:35:16 -07003726 result = GetFullPathNameW(path->wide,
3727 Py_ARRAY_LENGTH(woutbuf),
3728 woutbuf, &wtemp);
3729 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3730 woutbufp = PyMem_New(wchar_t, result);
3731 if (!woutbufp)
3732 return PyErr_NoMemory();
3733 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003734 }
Steve Dowercc16be82016-09-08 10:35:16 -07003735 if (result) {
3736 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3737 if (path->narrow)
3738 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3739 } else
3740 v = win32_error_object("GetFullPathNameW", path->object);
3741 if (woutbufp != woutbuf)
3742 PyMem_Free(woutbufp);
3743 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003744}
Brian Curtind40e6f72010-07-08 21:39:08 +00003745
Brian Curtind25aef52011-06-13 15:16:04 -05003746
Larry Hastings2f936352014-08-05 14:04:04 +10003747/*[clinic input]
3748os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003749
Steve Dower23ad6d02018-02-22 10:39:10 -08003750 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003751 /
3752
3753A helper function for samepath on windows.
3754[clinic start generated code]*/
3755
Larry Hastings2f936352014-08-05 14:04:04 +10003756static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003757os__getfinalpathname_impl(PyObject *module, path_t *path)
3758/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003759{
3760 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003761 wchar_t buf[MAXPATHLEN], *target_path = buf;
3762 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003763 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003764 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003765
Steve Dower23ad6d02018-02-22 10:39:10 -08003766 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003767 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003768 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003769 0, /* desired access */
3770 0, /* share mode */
3771 NULL, /* security attributes */
3772 OPEN_EXISTING,
3773 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3774 FILE_FLAG_BACKUP_SEMANTICS,
3775 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003776 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003777
Steve Dower23ad6d02018-02-22 10:39:10 -08003778 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003779 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003780 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003781
3782 /* We have a good handle to the target, use it to determine the
3783 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003784 while (1) {
3785 Py_BEGIN_ALLOW_THREADS
3786 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3787 buf_size, VOLUME_NAME_DOS);
3788 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003789
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003790 if (!result_length) {
3791 result = win32_error_object("GetFinalPathNameByHandleW",
3792 path->object);
3793 goto cleanup;
3794 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003795
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003796 if (result_length < buf_size) {
3797 break;
3798 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003799
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003800 wchar_t *tmp;
3801 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3802 result_length * sizeof(*tmp));
3803 if (!tmp) {
3804 result = PyErr_NoMemory();
3805 goto cleanup;
3806 }
3807
3808 buf_size = result_length;
3809 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003810 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003811
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003812 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003813 if (path->narrow)
3814 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003815
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003816cleanup:
3817 if (target_path != buf) {
3818 PyMem_Free(target_path);
3819 }
3820 CloseHandle(hFile);
3821 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003822}
Brian Curtin62857742010-09-06 17:07:27 +00003823
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003824/*[clinic input]
3825os._isdir
3826
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003827 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003828 /
3829
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003830Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003831[clinic start generated code]*/
3832
Brian Curtin9c669cc2011-06-08 18:17:18 -05003833static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003834os__isdir(PyObject *module, PyObject *arg)
3835/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003836{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003837 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003838 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3839
3840 if (!path_converter(arg, &path)) {
3841 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3842 PyErr_Clear();
3843 Py_RETURN_FALSE;
3844 }
3845 return NULL;
3846 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003847
Steve Dowerb22a6772016-07-17 20:49:38 -07003848 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003849 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003850 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003851
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003852 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003853 if (attributes == INVALID_FILE_ATTRIBUTES)
3854 Py_RETURN_FALSE;
3855
Brian Curtin9c669cc2011-06-08 18:17:18 -05003856 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3857 Py_RETURN_TRUE;
3858 else
3859 Py_RETURN_FALSE;
3860}
Tim Golden6b528062013-08-01 12:44:00 +01003861
Tim Golden6b528062013-08-01 12:44:00 +01003862
Larry Hastings2f936352014-08-05 14:04:04 +10003863/*[clinic input]
3864os._getvolumepathname
3865
Steve Dower23ad6d02018-02-22 10:39:10 -08003866 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003867
3868A helper function for ismount on Win32.
3869[clinic start generated code]*/
3870
Larry Hastings2f936352014-08-05 14:04:04 +10003871static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003872os__getvolumepathname_impl(PyObject *module, path_t *path)
3873/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003874{
3875 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003876 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003877 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003878 BOOL ret;
3879
Tim Golden6b528062013-08-01 12:44:00 +01003880 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003881 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003882
Victor Stinner850a18e2017-10-24 16:53:32 -07003883 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003884 PyErr_SetString(PyExc_OverflowError, "path too long");
3885 return NULL;
3886 }
3887
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003888 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003889 if (mountpath == NULL)
3890 return PyErr_NoMemory();
3891
3892 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003893 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003894 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003895 Py_END_ALLOW_THREADS
3896
3897 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003898 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003899 goto exit;
3900 }
3901 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003902 if (path->narrow)
3903 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003904
3905exit:
3906 PyMem_Free(mountpath);
3907 return result;
3908}
Tim Golden6b528062013-08-01 12:44:00 +01003909
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003910#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003911
Larry Hastings2f936352014-08-05 14:04:04 +10003912
3913/*[clinic input]
3914os.mkdir
3915
3916 path : path_t
3917
3918 mode: int = 0o777
3919
3920 *
3921
3922 dir_fd : dir_fd(requires='mkdirat') = None
3923
3924# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3925
3926Create a directory.
3927
3928If dir_fd is not None, it should be a file descriptor open to a directory,
3929 and path should be relative; path will then be relative to that directory.
3930dir_fd may not be implemented on your platform.
3931 If it is unavailable, using it will raise a NotImplementedError.
3932
3933The mode argument is ignored on Windows.
3934[clinic start generated code]*/
3935
Larry Hastings2f936352014-08-05 14:04:04 +10003936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003937os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3938/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003939{
3940 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003941
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003942#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003944 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003945 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003946
Larry Hastings2f936352014-08-05 14:04:04 +10003947 if (!result)
3948 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003949#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003950 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003951#if HAVE_MKDIRAT
3952 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003953 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003954 else
3955#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003956#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003957 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003958#else
Larry Hastings2f936352014-08-05 14:04:04 +10003959 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003960#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003962 if (result < 0)
3963 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003964#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003965 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003966}
3967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003968
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003969/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3970#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003971#include <sys/resource.h>
3972#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003973
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003974
3975#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003976/*[clinic input]
3977os.nice
3978
3979 increment: int
3980 /
3981
3982Add increment to the priority of process and return the new priority.
3983[clinic start generated code]*/
3984
Larry Hastings2f936352014-08-05 14:04:04 +10003985static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003986os_nice_impl(PyObject *module, int increment)
3987/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003988{
3989 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003990
Victor Stinner8c62be82010-05-06 00:08:46 +00003991 /* There are two flavours of 'nice': one that returns the new
3992 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003993 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003994 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003995
Victor Stinner8c62be82010-05-06 00:08:46 +00003996 If we are of the nice family that returns the new priority, we
3997 need to clear errno before the call, and check if errno is filled
3998 before calling posix_error() on a returnvalue of -1, because the
3999 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004000
Victor Stinner8c62be82010-05-06 00:08:46 +00004001 errno = 0;
4002 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004003#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 if (value == 0)
4005 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004006#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 if (value == -1 && errno != 0)
4008 /* either nice() or getpriority() returned an error */
4009 return posix_error();
4010 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004011}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004012#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004013
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004014
4015#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004016/*[clinic input]
4017os.getpriority
4018
4019 which: int
4020 who: int
4021
4022Return program scheduling priority.
4023[clinic start generated code]*/
4024
Larry Hastings2f936352014-08-05 14:04:04 +10004025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004026os_getpriority_impl(PyObject *module, int which, int who)
4027/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004028{
4029 int retval;
4030
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004031 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004032 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004033 if (errno != 0)
4034 return posix_error();
4035 return PyLong_FromLong((long)retval);
4036}
4037#endif /* HAVE_GETPRIORITY */
4038
4039
4040#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004041/*[clinic input]
4042os.setpriority
4043
4044 which: int
4045 who: int
4046 priority: int
4047
4048Set program scheduling priority.
4049[clinic start generated code]*/
4050
Larry Hastings2f936352014-08-05 14:04:04 +10004051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004052os_setpriority_impl(PyObject *module, int which, int who, int priority)
4053/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004054{
4055 int retval;
4056
4057 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004058 if (retval == -1)
4059 return posix_error();
4060 Py_RETURN_NONE;
4061}
4062#endif /* HAVE_SETPRIORITY */
4063
4064
Barry Warsaw53699e91996-12-10 23:23:01 +00004065static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004066internal_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 +00004067{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004068 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004069 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004070
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004071#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004073 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004074#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004075 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004076#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004077
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4079 (dst_dir_fd != DEFAULT_DIR_FD);
4080#ifndef HAVE_RENAMEAT
4081 if (dir_fd_specified) {
4082 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004083 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004084 }
4085#endif
4086
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087#ifdef MS_WINDOWS
4088 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004089 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090 Py_END_ALLOW_THREADS
4091
Larry Hastings2f936352014-08-05 14:04:04 +10004092 if (!result)
4093 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094
4095#else
Steve Dowercc16be82016-09-08 10:35:16 -07004096 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4097 PyErr_Format(PyExc_ValueError,
4098 "%s: src and dst must be the same type", function_name);
4099 return NULL;
4100 }
4101
Larry Hastings9cf065c2012-06-22 16:30:09 -07004102 Py_BEGIN_ALLOW_THREADS
4103#ifdef HAVE_RENAMEAT
4104 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004105 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004106 else
4107#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004108 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004109 Py_END_ALLOW_THREADS
4110
Larry Hastings2f936352014-08-05 14:04:04 +10004111 if (result)
4112 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004114 Py_RETURN_NONE;
4115}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116
Larry Hastings2f936352014-08-05 14:04:04 +10004117
4118/*[clinic input]
4119os.rename
4120
4121 src : path_t
4122 dst : path_t
4123 *
4124 src_dir_fd : dir_fd = None
4125 dst_dir_fd : dir_fd = None
4126
4127Rename a file or directory.
4128
4129If either src_dir_fd or dst_dir_fd is not None, it should be a file
4130 descriptor open to a directory, and the respective path string (src or dst)
4131 should be relative; the path will then be relative to that directory.
4132src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4133 If they are unavailable, using them will raise a NotImplementedError.
4134[clinic start generated code]*/
4135
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004137os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004138 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004139/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004140{
Larry Hastings2f936352014-08-05 14:04:04 +10004141 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004142}
4143
Larry Hastings2f936352014-08-05 14:04:04 +10004144
4145/*[clinic input]
4146os.replace = os.rename
4147
4148Rename a file or directory, overwriting the destination.
4149
4150If either src_dir_fd or dst_dir_fd is not None, it should be a file
4151 descriptor open to a directory, and the respective path string (src or dst)
4152 should be relative; the path will then be relative to that directory.
4153src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4154 If they are unavailable, using them will raise a NotImplementedError."
4155[clinic start generated code]*/
4156
Larry Hastings2f936352014-08-05 14:04:04 +10004157static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004158os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4159 int dst_dir_fd)
4160/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004161{
4162 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4163}
4164
4165
4166/*[clinic input]
4167os.rmdir
4168
4169 path: path_t
4170 *
4171 dir_fd: dir_fd(requires='unlinkat') = None
4172
4173Remove a directory.
4174
4175If dir_fd is not None, it should be a file descriptor open to a directory,
4176 and path should be relative; path will then be relative to that directory.
4177dir_fd may not be implemented on your platform.
4178 If it is unavailable, using it will raise a NotImplementedError.
4179[clinic start generated code]*/
4180
Larry Hastings2f936352014-08-05 14:04:04 +10004181static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004182os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4183/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004184{
4185 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004186
4187 Py_BEGIN_ALLOW_THREADS
4188#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004189 /* Windows, success=1, UNIX, success=0 */
4190 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004191#else
4192#ifdef HAVE_UNLINKAT
4193 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004194 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004195 else
4196#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004197 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004198#endif
4199 Py_END_ALLOW_THREADS
4200
Larry Hastings2f936352014-08-05 14:04:04 +10004201 if (result)
4202 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004203
Larry Hastings2f936352014-08-05 14:04:04 +10004204 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004205}
4206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004207
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004208#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004209#ifdef MS_WINDOWS
4210/*[clinic input]
4211os.system -> long
4212
4213 command: Py_UNICODE
4214
4215Execute the command in a subshell.
4216[clinic start generated code]*/
4217
Larry Hastings2f936352014-08-05 14:04:04 +10004218static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004219os_system_impl(PyObject *module, const Py_UNICODE *command)
4220/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004221{
4222 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004223 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004224 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004225 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004226 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004227 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004228 return result;
4229}
4230#else /* MS_WINDOWS */
4231/*[clinic input]
4232os.system -> long
4233
4234 command: FSConverter
4235
4236Execute the command in a subshell.
4237[clinic start generated code]*/
4238
Larry Hastings2f936352014-08-05 14:04:04 +10004239static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004240os_system_impl(PyObject *module, PyObject *command)
4241/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004242{
4243 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004244 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004245 Py_BEGIN_ALLOW_THREADS
4246 result = system(bytes);
4247 Py_END_ALLOW_THREADS
4248 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004249}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004250#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004251#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004252
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004253
Larry Hastings2f936352014-08-05 14:04:04 +10004254/*[clinic input]
4255os.umask
4256
4257 mask: int
4258 /
4259
4260Set the current numeric umask and return the previous umask.
4261[clinic start generated code]*/
4262
Larry Hastings2f936352014-08-05 14:04:04 +10004263static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004264os_umask_impl(PyObject *module, int mask)
4265/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004266{
4267 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004268 if (i < 0)
4269 return posix_error();
4270 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004271}
4272
Brian Curtind40e6f72010-07-08 21:39:08 +00004273#ifdef MS_WINDOWS
4274
4275/* override the default DeleteFileW behavior so that directory
4276symlinks can be removed with this function, the same as with
4277Unix symlinks */
4278BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4279{
4280 WIN32_FILE_ATTRIBUTE_DATA info;
4281 WIN32_FIND_DATAW find_data;
4282 HANDLE find_data_handle;
4283 int is_directory = 0;
4284 int is_link = 0;
4285
4286 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4287 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004288
Brian Curtind40e6f72010-07-08 21:39:08 +00004289 /* Get WIN32_FIND_DATA structure for the path to determine if
4290 it is a symlink */
4291 if(is_directory &&
4292 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4293 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4294
4295 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004296 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4297 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4298 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4299 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004300 FindClose(find_data_handle);
4301 }
4302 }
4303 }
4304
4305 if (is_directory && is_link)
4306 return RemoveDirectoryW(lpFileName);
4307
4308 return DeleteFileW(lpFileName);
4309}
4310#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004311
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312
Larry Hastings2f936352014-08-05 14:04:04 +10004313/*[clinic input]
4314os.unlink
4315
4316 path: path_t
4317 *
4318 dir_fd: dir_fd(requires='unlinkat')=None
4319
4320Remove a file (same as remove()).
4321
4322If dir_fd is not None, it should be a file descriptor open to a directory,
4323 and path should be relative; path will then be relative to that directory.
4324dir_fd may not be implemented on your platform.
4325 If it is unavailable, using it will raise a NotImplementedError.
4326
4327[clinic start generated code]*/
4328
Larry Hastings2f936352014-08-05 14:04:04 +10004329static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004330os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4331/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004332{
4333 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334
4335 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004336 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004337#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004338 /* Windows, success=1, UNIX, success=0 */
4339 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004340#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341#ifdef HAVE_UNLINKAT
4342 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004343 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004344 else
4345#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004346 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004347#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004348 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004349 Py_END_ALLOW_THREADS
4350
Larry Hastings2f936352014-08-05 14:04:04 +10004351 if (result)
4352 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004353
Larry Hastings2f936352014-08-05 14:04:04 +10004354 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004355}
4356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004357
Larry Hastings2f936352014-08-05 14:04:04 +10004358/*[clinic input]
4359os.remove = os.unlink
4360
4361Remove a file (same as unlink()).
4362
4363If dir_fd is not None, it should be a file descriptor open to a directory,
4364 and path should be relative; path will then be relative to that directory.
4365dir_fd may not be implemented on your platform.
4366 If it is unavailable, using it will raise a NotImplementedError.
4367[clinic start generated code]*/
4368
Larry Hastings2f936352014-08-05 14:04:04 +10004369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004370os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4371/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004372{
4373 return os_unlink_impl(module, path, dir_fd);
4374}
4375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004376
Larry Hastings605a62d2012-06-24 04:33:36 -07004377static PyStructSequence_Field uname_result_fields[] = {
4378 {"sysname", "operating system name"},
4379 {"nodename", "name of machine on network (implementation-defined)"},
4380 {"release", "operating system release"},
4381 {"version", "operating system version"},
4382 {"machine", "hardware identifier"},
4383 {NULL}
4384};
4385
4386PyDoc_STRVAR(uname_result__doc__,
4387"uname_result: Result from os.uname().\n\n\
4388This object may be accessed either as a tuple of\n\
4389 (sysname, nodename, release, version, machine),\n\
4390or via the attributes sysname, nodename, release, version, and machine.\n\
4391\n\
4392See os.uname for more information.");
4393
4394static PyStructSequence_Desc uname_result_desc = {
4395 "uname_result", /* name */
4396 uname_result__doc__, /* doc */
4397 uname_result_fields,
4398 5
4399};
4400
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004401static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004402
4403
4404#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004405/*[clinic input]
4406os.uname
4407
4408Return an object identifying the current operating system.
4409
4410The object behaves like a named tuple with the following fields:
4411 (sysname, nodename, release, version, machine)
4412
4413[clinic start generated code]*/
4414
Larry Hastings2f936352014-08-05 14:04:04 +10004415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004416os_uname_impl(PyObject *module)
4417/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004418{
Victor Stinner8c62be82010-05-06 00:08:46 +00004419 struct utsname u;
4420 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004421 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004422
Victor Stinner8c62be82010-05-06 00:08:46 +00004423 Py_BEGIN_ALLOW_THREADS
4424 res = uname(&u);
4425 Py_END_ALLOW_THREADS
4426 if (res < 0)
4427 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004428
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004429 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004430 if (value == NULL)
4431 return NULL;
4432
4433#define SET(i, field) \
4434 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004435 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004436 if (!o) { \
4437 Py_DECREF(value); \
4438 return NULL; \
4439 } \
4440 PyStructSequence_SET_ITEM(value, i, o); \
4441 } \
4442
4443 SET(0, u.sysname);
4444 SET(1, u.nodename);
4445 SET(2, u.release);
4446 SET(3, u.version);
4447 SET(4, u.machine);
4448
4449#undef SET
4450
4451 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004452}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004453#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004454
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004455
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456
4457typedef struct {
4458 int now;
4459 time_t atime_s;
4460 long atime_ns;
4461 time_t mtime_s;
4462 long mtime_ns;
4463} utime_t;
4464
4465/*
Victor Stinner484df002014-10-09 13:52:31 +02004466 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004467 * they also intentionally leak the declaration of a pointer named "time"
4468 */
4469#define UTIME_TO_TIMESPEC \
4470 struct timespec ts[2]; \
4471 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004472 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473 time = NULL; \
4474 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004475 ts[0].tv_sec = ut->atime_s; \
4476 ts[0].tv_nsec = ut->atime_ns; \
4477 ts[1].tv_sec = ut->mtime_s; \
4478 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004479 time = ts; \
4480 } \
4481
4482#define UTIME_TO_TIMEVAL \
4483 struct timeval tv[2]; \
4484 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004485 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486 time = NULL; \
4487 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004488 tv[0].tv_sec = ut->atime_s; \
4489 tv[0].tv_usec = ut->atime_ns / 1000; \
4490 tv[1].tv_sec = ut->mtime_s; \
4491 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492 time = tv; \
4493 } \
4494
4495#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004496 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004498 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499 time = NULL; \
4500 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004501 u.actime = ut->atime_s; \
4502 u.modtime = ut->mtime_s; \
4503 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004504 }
4505
4506#define UTIME_TO_TIME_T \
4507 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004508 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004509 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510 time = NULL; \
4511 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004512 timet[0] = ut->atime_s; \
4513 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004514 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004515 } \
4516
4517
Victor Stinner528a9ab2015-09-03 21:30:26 +02004518#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519
4520static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004521utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522{
4523#ifdef HAVE_UTIMENSAT
4524 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4525 UTIME_TO_TIMESPEC;
4526 return utimensat(dir_fd, path, time, flags);
4527#elif defined(HAVE_FUTIMESAT)
4528 UTIME_TO_TIMEVAL;
4529 /*
4530 * follow_symlinks will never be false here;
4531 * we only allow !follow_symlinks and dir_fd together
4532 * if we have utimensat()
4533 */
4534 assert(follow_symlinks);
4535 return futimesat(dir_fd, path, time);
4536#endif
4537}
4538
Larry Hastings2f936352014-08-05 14:04:04 +10004539 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4540#else
4541 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542#endif
4543
Victor Stinner528a9ab2015-09-03 21:30:26 +02004544#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545
4546static int
Victor Stinner484df002014-10-09 13:52:31 +02004547utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548{
4549#ifdef HAVE_FUTIMENS
4550 UTIME_TO_TIMESPEC;
4551 return futimens(fd, time);
4552#else
4553 UTIME_TO_TIMEVAL;
4554 return futimes(fd, time);
4555#endif
4556}
4557
Larry Hastings2f936352014-08-05 14:04:04 +10004558 #define PATH_UTIME_HAVE_FD 1
4559#else
4560 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561#endif
4562
Victor Stinner5ebae872015-09-22 01:29:33 +02004563#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4564# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4565#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566
Victor Stinner4552ced2015-09-21 22:37:15 +02004567#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004568
4569static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004570utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004571{
4572#ifdef HAVE_UTIMENSAT
4573 UTIME_TO_TIMESPEC;
4574 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4575#else
4576 UTIME_TO_TIMEVAL;
4577 return lutimes(path, time);
4578#endif
4579}
4580
4581#endif
4582
4583#ifndef MS_WINDOWS
4584
4585static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004586utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587{
4588#ifdef HAVE_UTIMENSAT
4589 UTIME_TO_TIMESPEC;
4590 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4591#elif defined(HAVE_UTIMES)
4592 UTIME_TO_TIMEVAL;
4593 return utimes(path, time);
4594#elif defined(HAVE_UTIME_H)
4595 UTIME_TO_UTIMBUF;
4596 return utime(path, time);
4597#else
4598 UTIME_TO_TIME_T;
4599 return utime(path, time);
4600#endif
4601}
4602
4603#endif
4604
Larry Hastings76ad59b2012-05-03 00:30:07 -07004605static int
4606split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4607{
4608 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004609 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004610 divmod = PyNumber_Divmod(py_long, billion);
4611 if (!divmod)
4612 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004613 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4614 PyErr_Format(PyExc_TypeError,
4615 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4616 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4617 goto exit;
4618 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004619 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4620 if ((*s == -1) && PyErr_Occurred())
4621 goto exit;
4622 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004623 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004624 goto exit;
4625
4626 result = 1;
4627exit:
4628 Py_XDECREF(divmod);
4629 return result;
4630}
4631
Larry Hastings2f936352014-08-05 14:04:04 +10004632
4633/*[clinic input]
4634os.utime
4635
4636 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4637 times: object = NULL
4638 *
4639 ns: object = NULL
4640 dir_fd: dir_fd(requires='futimensat') = None
4641 follow_symlinks: bool=True
4642
Martin Panter0ff89092015-09-09 01:56:53 +00004643# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004644
4645Set the access and modified time of path.
4646
4647path may always be specified as a string.
4648On some platforms, path may also be specified as an open file descriptor.
4649 If this functionality is unavailable, using it raises an exception.
4650
4651If times is not None, it must be a tuple (atime, mtime);
4652 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004653If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004654 atime_ns and mtime_ns should be expressed as integer nanoseconds
4655 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004656If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004657Specifying tuples for both times and ns is an error.
4658
4659If dir_fd is not None, it should be a file descriptor open to a directory,
4660 and path should be relative; path will then be relative to that directory.
4661If follow_symlinks is False, and the last element of the path is a symbolic
4662 link, utime will modify the symbolic link itself instead of the file the
4663 link points to.
4664It is an error to use dir_fd or follow_symlinks when specifying path
4665 as an open file descriptor.
4666dir_fd and follow_symlinks may not be available on your platform.
4667 If they are unavailable, using them will raise a NotImplementedError.
4668
4669[clinic start generated code]*/
4670
Larry Hastings2f936352014-08-05 14:04:04 +10004671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004672os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4673 int dir_fd, int follow_symlinks)
4674/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004675{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004676#ifdef MS_WINDOWS
4677 HANDLE hFile;
4678 FILETIME atime, mtime;
4679#else
4680 int result;
4681#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004682
Larry Hastings2f936352014-08-05 14:04:04 +10004683 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004684
Christian Heimesb3c87242013-08-01 00:08:16 +02004685 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004686
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687 if (times && (times != Py_None) && ns) {
4688 PyErr_SetString(PyExc_ValueError,
4689 "utime: you may specify either 'times'"
4690 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004691 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004692 }
4693
4694 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004695 time_t a_sec, m_sec;
4696 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004698 PyErr_SetString(PyExc_TypeError,
4699 "utime: 'times' must be either"
4700 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004701 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004702 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004704 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004705 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004706 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004707 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004708 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004709 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004710 utime.atime_s = a_sec;
4711 utime.atime_ns = a_nsec;
4712 utime.mtime_s = m_sec;
4713 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004714 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004716 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717 PyErr_SetString(PyExc_TypeError,
4718 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004719 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004720 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004722 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004723 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004724 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004726 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004727 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004728 }
4729 else {
4730 /* times and ns are both None/unspecified. use "now". */
4731 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004732 }
4733
Victor Stinner4552ced2015-09-21 22:37:15 +02004734#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004736 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004738
Larry Hastings2f936352014-08-05 14:04:04 +10004739 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4740 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4741 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004742 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004743
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744#if !defined(HAVE_UTIMENSAT)
4745 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004746 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 "utime: cannot use dir_fd and follow_symlinks "
4748 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004749 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 }
4751#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004752
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004753#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004755 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4756 NULL, OPEN_EXISTING,
4757 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 Py_END_ALLOW_THREADS
4759 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004760 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004761 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004762 }
4763
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004765 GetSystemTimeAsFileTime(&mtime);
4766 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004767 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004768 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004769 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4770 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004771 }
4772 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4773 /* Avoid putting the file name into the error here,
4774 as that may confuse the user into believing that
4775 something is wrong with the file, when it also
4776 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004777 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004778 CloseHandle(hFile);
4779 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004781 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004782#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004784
Victor Stinner4552ced2015-09-21 22:37:15 +02004785#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004786 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004787 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004789#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790
Victor Stinner528a9ab2015-09-03 21:30:26 +02004791#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004793 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 else
4795#endif
4796
Victor Stinner528a9ab2015-09-03 21:30:26 +02004797#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004798 if (path->fd != -1)
4799 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800 else
4801#endif
4802
Larry Hastings2f936352014-08-05 14:04:04 +10004803 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804
4805 Py_END_ALLOW_THREADS
4806
4807 if (result < 0) {
4808 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004809 posix_error();
4810 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004811 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004812
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004813#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004815 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004816}
4817
Guido van Rossum3b066191991-06-04 19:40:25 +00004818/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004819
Larry Hastings2f936352014-08-05 14:04:04 +10004820
4821/*[clinic input]
4822os._exit
4823
4824 status: int
4825
4826Exit to the system with specified status, without normal exit processing.
4827[clinic start generated code]*/
4828
Larry Hastings2f936352014-08-05 14:04:04 +10004829static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004830os__exit_impl(PyObject *module, int status)
4831/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004832{
4833 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004835}
4836
Steve Dowercc16be82016-09-08 10:35:16 -07004837#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4838#define EXECV_CHAR wchar_t
4839#else
4840#define EXECV_CHAR char
4841#endif
4842
Martin v. Löwis114619e2002-10-07 06:44:21 +00004843#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4844static void
Steve Dowercc16be82016-09-08 10:35:16 -07004845free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004846{
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 Py_ssize_t i;
4848 for (i = 0; i < count; i++)
4849 PyMem_Free(array[i]);
4850 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004851}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004852
Berker Peksag81816462016-09-15 20:19:47 +03004853static int
4854fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004855{
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004857 PyObject *ub;
4858 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004859#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004860 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004861 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004862 *out = PyUnicode_AsWideCharString(ub, &size);
4863 if (*out)
4864 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004865#else
Berker Peksag81816462016-09-15 20:19:47 +03004866 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004868 size = PyBytes_GET_SIZE(ub);
4869 *out = PyMem_Malloc(size + 1);
4870 if (*out) {
4871 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4872 result = 1;
4873 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004874 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004875#endif
Berker Peksag81816462016-09-15 20:19:47 +03004876 Py_DECREF(ub);
4877 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004878}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004879#endif
4880
Ross Lagerwall7807c352011-03-17 20:20:30 +02004881#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004882static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004883parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4884{
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 Py_ssize_t i, pos, envc;
4886 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004887 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004888 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004889
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 i = PyMapping_Size(env);
4891 if (i < 0)
4892 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004893 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004894 if (envlist == NULL) {
4895 PyErr_NoMemory();
4896 return NULL;
4897 }
4898 envc = 0;
4899 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004900 if (!keys)
4901 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004903 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004904 goto error;
4905 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4906 PyErr_Format(PyExc_TypeError,
4907 "env.keys() or env.values() is not a list");
4908 goto error;
4909 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004910
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 for (pos = 0; pos < i; pos++) {
4912 key = PyList_GetItem(keys, pos);
4913 val = PyList_GetItem(vals, pos);
4914 if (!key || !val)
4915 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004916
Berker Peksag81816462016-09-15 20:19:47 +03004917#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4918 if (!PyUnicode_FSDecoder(key, &key2))
4919 goto error;
4920 if (!PyUnicode_FSDecoder(val, &val2)) {
4921 Py_DECREF(key2);
4922 goto error;
4923 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004924 /* Search from index 1 because on Windows starting '=' is allowed for
4925 defining hidden environment variables. */
4926 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4927 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4928 {
4929 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004930 Py_DECREF(key2);
4931 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004932 goto error;
4933 }
Berker Peksag81816462016-09-15 20:19:47 +03004934 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4935#else
4936 if (!PyUnicode_FSConverter(key, &key2))
4937 goto error;
4938 if (!PyUnicode_FSConverter(val, &val2)) {
4939 Py_DECREF(key2);
4940 goto error;
4941 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004942 if (PyBytes_GET_SIZE(key2) == 0 ||
4943 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4944 {
4945 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004946 Py_DECREF(key2);
4947 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004948 goto error;
4949 }
Berker Peksag81816462016-09-15 20:19:47 +03004950 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4951 PyBytes_AS_STRING(val2));
4952#endif
4953 Py_DECREF(key2);
4954 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004955 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004957
4958 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4959 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 goto error;
4961 }
Berker Peksag81816462016-09-15 20:19:47 +03004962
Steve Dowercc16be82016-09-08 10:35:16 -07004963 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004964 }
4965 Py_DECREF(vals);
4966 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004967
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 envlist[envc] = 0;
4969 *envc_ptr = envc;
4970 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004971
4972error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 Py_XDECREF(keys);
4974 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004975 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004976 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004977}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004978
Steve Dowercc16be82016-09-08 10:35:16 -07004979static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004980parse_arglist(PyObject* argv, Py_ssize_t *argc)
4981{
4982 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004983 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004984 if (argvlist == NULL) {
4985 PyErr_NoMemory();
4986 return NULL;
4987 }
4988 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004989 PyObject* item = PySequence_ITEM(argv, i);
4990 if (item == NULL)
4991 goto fail;
4992 if (!fsconvert_strdup(item, &argvlist[i])) {
4993 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004994 goto fail;
4995 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004996 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 }
4998 argvlist[*argc] = NULL;
4999 return argvlist;
5000fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005001 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005002 free_string_array(argvlist, *argc);
5003 return NULL;
5004}
Steve Dowercc16be82016-09-08 10:35:16 -07005005
Ross Lagerwall7807c352011-03-17 20:20:30 +02005006#endif
5007
Larry Hastings2f936352014-08-05 14:04:04 +10005008
Ross Lagerwall7807c352011-03-17 20:20:30 +02005009#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005010/*[clinic input]
5011os.execv
5012
Steve Dowercc16be82016-09-08 10:35:16 -07005013 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005014 Path of executable file.
5015 argv: object
5016 Tuple or list of strings.
5017 /
5018
5019Execute an executable path with arguments, replacing current process.
5020[clinic start generated code]*/
5021
Larry Hastings2f936352014-08-05 14:04:04 +10005022static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005023os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5024/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005025{
Steve Dowercc16be82016-09-08 10:35:16 -07005026 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005027 Py_ssize_t argc;
5028
5029 /* execv has two arguments: (path, argv), where
5030 argv is a list or tuple of strings. */
5031
Ross Lagerwall7807c352011-03-17 20:20:30 +02005032 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5033 PyErr_SetString(PyExc_TypeError,
5034 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005035 return NULL;
5036 }
5037 argc = PySequence_Size(argv);
5038 if (argc < 1) {
5039 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005040 return NULL;
5041 }
5042
5043 argvlist = parse_arglist(argv, &argc);
5044 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005045 return NULL;
5046 }
Steve Dowerbce26262016-11-19 19:17:26 -08005047 if (!argvlist[0][0]) {
5048 PyErr_SetString(PyExc_ValueError,
5049 "execv() arg 2 first element cannot be empty");
5050 free_string_array(argvlist, argc);
5051 return NULL;
5052 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053
Steve Dowerbce26262016-11-19 19:17:26 -08005054 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005055#ifdef HAVE_WEXECV
5056 _wexecv(path->wide, argvlist);
5057#else
5058 execv(path->narrow, argvlist);
5059#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005060 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061
5062 /* If we get here it's definitely an error */
5063
5064 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005065 return posix_error();
5066}
5067
Larry Hastings2f936352014-08-05 14:04:04 +10005068
5069/*[clinic input]
5070os.execve
5071
5072 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5073 Path of executable file.
5074 argv: object
5075 Tuple or list of strings.
5076 env: object
5077 Dictionary of strings mapping to strings.
5078
5079Execute an executable path with arguments, replacing current process.
5080[clinic start generated code]*/
5081
Larry Hastings2f936352014-08-05 14:04:04 +10005082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005083os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5084/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005085{
Steve Dowercc16be82016-09-08 10:35:16 -07005086 EXECV_CHAR **argvlist = NULL;
5087 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005088 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005089
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 /* execve has three arguments: (path, argv, env), where
5091 argv is a list or tuple of strings and env is a dictionary
5092 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005093
Ross Lagerwall7807c352011-03-17 20:20:30 +02005094 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005096 "execve: argv must be a tuple or list");
5097 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005099 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005100 if (argc < 1) {
5101 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5102 return NULL;
5103 }
5104
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 if (!PyMapping_Check(env)) {
5106 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005107 "execve: environment must be a mapping object");
5108 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005110
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005113 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 }
Steve Dowerbce26262016-11-19 19:17:26 -08005115 if (!argvlist[0][0]) {
5116 PyErr_SetString(PyExc_ValueError,
5117 "execve: argv first element cannot be empty");
5118 goto fail;
5119 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005120
Victor Stinner8c62be82010-05-06 00:08:46 +00005121 envlist = parse_envlist(env, &envc);
5122 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005123 goto fail;
5124
Steve Dowerbce26262016-11-19 19:17:26 -08005125 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005127 if (path->fd > -1)
5128 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005129 else
5130#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005131#ifdef HAVE_WEXECV
5132 _wexecve(path->wide, argvlist, envlist);
5133#else
Larry Hastings2f936352014-08-05 14:04:04 +10005134 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005135#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005136 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005137
5138 /* If we get here it's definitely an error */
5139
Alexey Izbyshev83460312018-10-20 03:28:22 +03005140 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141
Steve Dowercc16be82016-09-08 10:35:16 -07005142 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005143 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144 if (argvlist)
5145 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005146 return NULL;
5147}
Steve Dowercc16be82016-09-08 10:35:16 -07005148
Larry Hastings9cf065c2012-06-22 16:30:09 -07005149#endif /* HAVE_EXECV */
5150
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005151#ifdef HAVE_POSIX_SPAWN
5152
5153enum posix_spawn_file_actions_identifier {
5154 POSIX_SPAWN_OPEN,
5155 POSIX_SPAWN_CLOSE,
5156 POSIX_SPAWN_DUP2
5157};
5158
William Orr81574b82018-10-01 22:19:56 -07005159#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005160static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005161convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005162#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005163
5164static int
5165parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask,
5166 PyObject *setsigdef, PyObject *scheduler,
5167 posix_spawnattr_t *attrp)
5168{
5169 long all_flags = 0;
5170
5171 errno = posix_spawnattr_init(attrp);
5172 if (errno) {
5173 posix_error();
5174 return -1;
5175 }
5176
5177 if (setpgroup) {
5178 pid_t pgid = PyLong_AsPid(setpgroup);
5179 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5180 goto fail;
5181 }
5182 errno = posix_spawnattr_setpgroup(attrp, pgid);
5183 if (errno) {
5184 posix_error();
5185 goto fail;
5186 }
5187 all_flags |= POSIX_SPAWN_SETPGROUP;
5188 }
5189
5190 if (resetids) {
5191 all_flags |= POSIX_SPAWN_RESETIDS;
5192 }
5193
5194 if (setsigmask) {
5195 sigset_t set;
5196 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5197 goto fail;
5198 }
5199 errno = posix_spawnattr_setsigmask(attrp, &set);
5200 if (errno) {
5201 posix_error();
5202 goto fail;
5203 }
5204 all_flags |= POSIX_SPAWN_SETSIGMASK;
5205 }
5206
5207 if (setsigdef) {
5208 sigset_t set;
5209 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5210 goto fail;
5211 }
5212 errno = posix_spawnattr_setsigdefault(attrp, &set);
5213 if (errno) {
5214 posix_error();
5215 goto fail;
5216 }
5217 all_flags |= POSIX_SPAWN_SETSIGDEF;
5218 }
5219
5220 if (scheduler) {
5221#ifdef POSIX_SPAWN_SETSCHEDULER
5222 PyObject *py_schedpolicy;
5223 struct sched_param schedparam;
5224
5225 if (!PyArg_ParseTuple(scheduler, "OO&"
5226 ";A scheduler tuple must have two elements",
5227 &py_schedpolicy, convert_sched_param, &schedparam)) {
5228 goto fail;
5229 }
5230 if (py_schedpolicy != Py_None) {
5231 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5232
5233 if (schedpolicy == -1 && PyErr_Occurred()) {
5234 goto fail;
5235 }
5236 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5237 if (errno) {
5238 posix_error();
5239 goto fail;
5240 }
5241 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5242 }
5243 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5244 if (errno) {
5245 posix_error();
5246 goto fail;
5247 }
5248 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5249#else
5250 PyErr_SetString(PyExc_NotImplementedError,
5251 "The scheduler option is not supported in this system.");
5252 goto fail;
5253#endif
5254 }
5255
5256 errno = posix_spawnattr_setflags(attrp, all_flags);
5257 if (errno) {
5258 posix_error();
5259 goto fail;
5260 }
5261
5262 return 0;
5263
5264fail:
5265 (void)posix_spawnattr_destroy(attrp);
5266 return -1;
5267}
5268
5269static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005270parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005271 posix_spawn_file_actions_t *file_actionsp,
5272 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005273{
5274 PyObject *seq;
5275 PyObject *file_action = NULL;
5276 PyObject *tag_obj;
5277
5278 seq = PySequence_Fast(file_actions,
5279 "file_actions must be a sequence or None");
5280 if (seq == NULL) {
5281 return -1;
5282 }
5283
5284 errno = posix_spawn_file_actions_init(file_actionsp);
5285 if (errno) {
5286 posix_error();
5287 Py_DECREF(seq);
5288 return -1;
5289 }
5290
5291 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5292 file_action = PySequence_Fast_GET_ITEM(seq, i);
5293 Py_INCREF(file_action);
5294 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5295 PyErr_SetString(PyExc_TypeError,
5296 "Each file_actions element must be a non-empty tuple");
5297 goto fail;
5298 }
5299 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5300 if (tag == -1 && PyErr_Occurred()) {
5301 goto fail;
5302 }
5303
5304 /* Populate the file_actions object */
5305 switch (tag) {
5306 case POSIX_SPAWN_OPEN: {
5307 int fd, oflag;
5308 PyObject *path;
5309 unsigned long mode;
5310 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5311 ";A open file_action tuple must have 5 elements",
5312 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5313 &oflag, &mode))
5314 {
5315 goto fail;
5316 }
Pablo Galindocb970732018-06-19 09:19:50 +01005317 if (PyList_Append(temp_buffer, path)) {
5318 Py_DECREF(path);
5319 goto fail;
5320 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005321 errno = posix_spawn_file_actions_addopen(file_actionsp,
5322 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005323 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005324 if (errno) {
5325 posix_error();
5326 goto fail;
5327 }
5328 break;
5329 }
5330 case POSIX_SPAWN_CLOSE: {
5331 int fd;
5332 if (!PyArg_ParseTuple(file_action, "Oi"
5333 ";A close file_action tuple must have 2 elements",
5334 &tag_obj, &fd))
5335 {
5336 goto fail;
5337 }
5338 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5339 if (errno) {
5340 posix_error();
5341 goto fail;
5342 }
5343 break;
5344 }
5345 case POSIX_SPAWN_DUP2: {
5346 int fd1, fd2;
5347 if (!PyArg_ParseTuple(file_action, "Oii"
5348 ";A dup2 file_action tuple must have 3 elements",
5349 &tag_obj, &fd1, &fd2))
5350 {
5351 goto fail;
5352 }
5353 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5354 fd1, fd2);
5355 if (errno) {
5356 posix_error();
5357 goto fail;
5358 }
5359 break;
5360 }
5361 default: {
5362 PyErr_SetString(PyExc_TypeError,
5363 "Unknown file_actions identifier");
5364 goto fail;
5365 }
5366 }
5367 Py_DECREF(file_action);
5368 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005369
Serhiy Storchakaef347532018-05-01 16:45:04 +03005370 Py_DECREF(seq);
5371 return 0;
5372
5373fail:
5374 Py_DECREF(seq);
5375 Py_DECREF(file_action);
5376 (void)posix_spawn_file_actions_destroy(file_actionsp);
5377 return -1;
5378}
5379
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005380/*[clinic input]
5381
5382os.posix_spawn
5383 path: path_t
5384 Path of executable file.
5385 argv: object
5386 Tuple or list of strings.
5387 env: object
5388 Dictionary of strings mapping to strings.
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005389 /
Pablo Galindo254a4662018-09-07 16:44:24 +01005390 *
Serhiy Storchakad700f972018-09-08 14:48:18 +03005391 file_actions: object(c_default='NULL') = ()
5392 A sequence of file action tuples.
Pablo Galindo254a4662018-09-07 16:44:24 +01005393 setpgroup: object = NULL
5394 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5395 resetids: bool(accept={int}) = False
5396 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
5397 setsigmask: object(c_default='NULL') = ()
5398 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5399 setsigdef: object(c_default='NULL') = ()
5400 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5401 scheduler: object = NULL
5402 A tuple with the scheduler policy (optional) and parameters.
Serhiy Storchakad700f972018-09-08 14:48:18 +03005403
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005404Execute the program specified by path in a new process.
5405[clinic start generated code]*/
5406
5407static PyObject *
5408os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
Pablo Galindo254a4662018-09-07 16:44:24 +01005409 PyObject *env, PyObject *file_actions,
5410 PyObject *setpgroup, int resetids, PyObject *setsigmask,
5411 PyObject *setsigdef, PyObject *scheduler)
Serhiy Storchakad700f972018-09-08 14:48:18 +03005412/*[clinic end generated code: output=45dfa4c515d09f2c input=2891c2f1d457e39b]*/
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005413{
5414 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005415 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005416 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005417 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005418 posix_spawnattr_t attr;
5419 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005420 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005421 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005422 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005423 pid_t pid;
5424 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005425
5426 /* posix_spawn has three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005427 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005428 like posix.environ. */
5429
Serhiy Storchakaef347532018-05-01 16:45:04 +03005430 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005431 PyErr_SetString(PyExc_TypeError,
5432 "posix_spawn: argv must be a tuple or list");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005433 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005434 }
5435 argc = PySequence_Size(argv);
5436 if (argc < 1) {
5437 PyErr_SetString(PyExc_ValueError, "posix_spawn: argv must not be empty");
5438 return NULL;
5439 }
5440
5441 if (!PyMapping_Check(env)) {
5442 PyErr_SetString(PyExc_TypeError,
5443 "posix_spawn: environment must be a mapping object");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005444 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005445 }
5446
5447 argvlist = parse_arglist(argv, &argc);
5448 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005449 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005450 }
5451 if (!argvlist[0][0]) {
5452 PyErr_SetString(PyExc_ValueError,
5453 "posix_spawn: argv first element cannot be empty");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005454 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005455 }
5456
5457 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005458 if (envlist == NULL) {
5459 goto exit;
5460 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005461
Serhiy Storchakad700f972018-09-08 14:48:18 +03005462 if (file_actions != NULL) {
Pablo Galindocb970732018-06-19 09:19:50 +01005463 /* There is a bug in old versions of glibc that makes some of the
5464 * helper functions for manipulating file actions not copy the provided
5465 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5466 * copy the value of path for some old versions of glibc (<2.20).
5467 * The use of temp_buffer here is a workaround that keeps the
5468 * python objects that own the buffers alive until posix_spawn gets called.
5469 * Check https://bugs.python.org/issue33630 and
5470 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5471 temp_buffer = PyList_New(0);
5472 if (!temp_buffer) {
5473 goto exit;
5474 }
5475 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005476 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005477 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005478 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005479 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005480
Pablo Galindo254a4662018-09-07 16:44:24 +01005481 if (parse_posix_spawn_flags(setpgroup, resetids, setsigmask,
5482 setsigdef, scheduler, &attr)) {
5483 goto exit;
5484 }
5485 attrp = &attr;
5486
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005487 _Py_BEGIN_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005488 err_code = posix_spawn(&pid, path->narrow,
Pablo Galindo254a4662018-09-07 16:44:24 +01005489 file_actionsp, attrp, argvlist, envlist);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005490 _Py_END_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005491 if (err_code) {
5492 errno = err_code;
5493 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005494 goto exit;
5495 }
5496 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005497
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005498exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005499 if (file_actionsp) {
5500 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005501 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005502 if (attrp) {
5503 (void)posix_spawnattr_destroy(attrp);
5504 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005505 if (envlist) {
5506 free_string_array(envlist, envc);
5507 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005508 if (argvlist) {
5509 free_string_array(argvlist, argc);
5510 }
Pablo Galindocb970732018-06-19 09:19:50 +01005511 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005512 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005513}
5514#endif /* HAVE_POSIX_SPAWN */
5515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005516
Steve Dowercc16be82016-09-08 10:35:16 -07005517#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005518/*[clinic input]
5519os.spawnv
5520
5521 mode: int
5522 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005523 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005524 Path of executable file.
5525 argv: object
5526 Tuple or list of strings.
5527 /
5528
5529Execute the program specified by path in a new process.
5530[clinic start generated code]*/
5531
Larry Hastings2f936352014-08-05 14:04:04 +10005532static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005533os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5534/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005535{
Steve Dowercc16be82016-09-08 10:35:16 -07005536 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005537 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005538 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005539 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005540 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005541
Victor Stinner8c62be82010-05-06 00:08:46 +00005542 /* spawnv has three arguments: (mode, path, argv), where
5543 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005544
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 if (PyList_Check(argv)) {
5546 argc = PyList_Size(argv);
5547 getitem = PyList_GetItem;
5548 }
5549 else if (PyTuple_Check(argv)) {
5550 argc = PyTuple_Size(argv);
5551 getitem = PyTuple_GetItem;
5552 }
5553 else {
5554 PyErr_SetString(PyExc_TypeError,
5555 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005556 return NULL;
5557 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005558 if (argc == 0) {
5559 PyErr_SetString(PyExc_ValueError,
5560 "spawnv() arg 2 cannot be empty");
5561 return NULL;
5562 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005563
Steve Dowercc16be82016-09-08 10:35:16 -07005564 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005565 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 return PyErr_NoMemory();
5567 }
5568 for (i = 0; i < argc; i++) {
5569 if (!fsconvert_strdup((*getitem)(argv, i),
5570 &argvlist[i])) {
5571 free_string_array(argvlist, i);
5572 PyErr_SetString(
5573 PyExc_TypeError,
5574 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005575 return NULL;
5576 }
Steve Dower93ff8722016-11-19 19:03:54 -08005577 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005578 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005579 PyErr_SetString(
5580 PyExc_ValueError,
5581 "spawnv() arg 2 first element cannot be empty");
5582 return NULL;
5583 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005584 }
5585 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005586
Victor Stinner8c62be82010-05-06 00:08:46 +00005587 if (mode == _OLD_P_OVERLAY)
5588 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005589
Victor Stinner8c62be82010-05-06 00:08:46 +00005590 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005591 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005592#ifdef HAVE_WSPAWNV
5593 spawnval = _wspawnv(mode, path->wide, argvlist);
5594#else
5595 spawnval = _spawnv(mode, path->narrow, argvlist);
5596#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005597 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005598 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005599
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005601
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 if (spawnval == -1)
5603 return posix_error();
5604 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005605 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005606}
5607
Larry Hastings2f936352014-08-05 14:04:04 +10005608/*[clinic input]
5609os.spawnve
5610
5611 mode: int
5612 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005613 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005614 Path of executable file.
5615 argv: object
5616 Tuple or list of strings.
5617 env: object
5618 Dictionary of strings mapping to strings.
5619 /
5620
5621Execute the program specified by path in a new process.
5622[clinic start generated code]*/
5623
Larry Hastings2f936352014-08-05 14:04:04 +10005624static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005625os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005626 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005627/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005628{
Steve Dowercc16be82016-09-08 10:35:16 -07005629 EXECV_CHAR **argvlist;
5630 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005631 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005632 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005633 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005634 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005635 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005636
Victor Stinner8c62be82010-05-06 00:08:46 +00005637 /* spawnve has four arguments: (mode, path, argv, env), where
5638 argv is a list or tuple of strings and env is a dictionary
5639 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005640
Victor Stinner8c62be82010-05-06 00:08:46 +00005641 if (PyList_Check(argv)) {
5642 argc = PyList_Size(argv);
5643 getitem = PyList_GetItem;
5644 }
5645 else if (PyTuple_Check(argv)) {
5646 argc = PyTuple_Size(argv);
5647 getitem = PyTuple_GetItem;
5648 }
5649 else {
5650 PyErr_SetString(PyExc_TypeError,
5651 "spawnve() arg 2 must be a tuple or list");
5652 goto fail_0;
5653 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005654 if (argc == 0) {
5655 PyErr_SetString(PyExc_ValueError,
5656 "spawnve() arg 2 cannot be empty");
5657 goto fail_0;
5658 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005659 if (!PyMapping_Check(env)) {
5660 PyErr_SetString(PyExc_TypeError,
5661 "spawnve() arg 3 must be a mapping object");
5662 goto fail_0;
5663 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005664
Steve Dowercc16be82016-09-08 10:35:16 -07005665 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005666 if (argvlist == NULL) {
5667 PyErr_NoMemory();
5668 goto fail_0;
5669 }
5670 for (i = 0; i < argc; i++) {
5671 if (!fsconvert_strdup((*getitem)(argv, i),
5672 &argvlist[i]))
5673 {
5674 lastarg = i;
5675 goto fail_1;
5676 }
Steve Dowerbce26262016-11-19 19:17:26 -08005677 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005678 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005679 PyErr_SetString(
5680 PyExc_ValueError,
5681 "spawnv() arg 2 first element cannot be empty");
5682 goto fail_1;
5683 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005684 }
5685 lastarg = argc;
5686 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005687
Victor Stinner8c62be82010-05-06 00:08:46 +00005688 envlist = parse_envlist(env, &envc);
5689 if (envlist == NULL)
5690 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005691
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 if (mode == _OLD_P_OVERLAY)
5693 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005694
Victor Stinner8c62be82010-05-06 00:08:46 +00005695 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005696 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005697#ifdef HAVE_WSPAWNV
5698 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5699#else
5700 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5701#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005702 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005703 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005704
Victor Stinner8c62be82010-05-06 00:08:46 +00005705 if (spawnval == -1)
5706 (void) posix_error();
5707 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005708 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005709
Victor Stinner8c62be82010-05-06 00:08:46 +00005710 while (--envc >= 0)
5711 PyMem_DEL(envlist[envc]);
5712 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005713 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005714 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005715 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005716 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005717}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005718
Guido van Rossuma1065681999-01-25 23:20:23 +00005719#endif /* HAVE_SPAWNV */
5720
5721
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005722#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005723
5724/* Helper function to validate arguments.
5725 Returns 0 on success. non-zero on failure with a TypeError raised.
5726 If obj is non-NULL it must be callable. */
5727static int
5728check_null_or_callable(PyObject *obj, const char* obj_name)
5729{
5730 if (obj && !PyCallable_Check(obj)) {
5731 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5732 obj_name, Py_TYPE(obj)->tp_name);
5733 return -1;
5734 }
5735 return 0;
5736}
5737
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005738/*[clinic input]
5739os.register_at_fork
5740
Gregory P. Smith163468a2017-05-29 10:03:41 -07005741 *
5742 before: object=NULL
5743 A callable to be called in the parent before the fork() syscall.
5744 after_in_child: object=NULL
5745 A callable to be called in the child after fork().
5746 after_in_parent: object=NULL
5747 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005748
Gregory P. Smith163468a2017-05-29 10:03:41 -07005749Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005750
Gregory P. Smith163468a2017-05-29 10:03:41 -07005751'before' callbacks are called in reverse order.
5752'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005753
5754[clinic start generated code]*/
5755
5756static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005757os_register_at_fork_impl(PyObject *module, PyObject *before,
5758 PyObject *after_in_child, PyObject *after_in_parent)
5759/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005760{
5761 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005762
Gregory P. Smith163468a2017-05-29 10:03:41 -07005763 if (!before && !after_in_child && !after_in_parent) {
5764 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5765 return NULL;
5766 }
5767 if (check_null_or_callable(before, "before") ||
5768 check_null_or_callable(after_in_child, "after_in_child") ||
5769 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005770 return NULL;
5771 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005772 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005773
Gregory P. Smith163468a2017-05-29 10:03:41 -07005774 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005775 return NULL;
5776 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005777 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005778 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005779 }
5780 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5781 return NULL;
5782 }
5783 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005784}
5785#endif /* HAVE_FORK */
5786
5787
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005788#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005789/*[clinic input]
5790os.fork1
5791
5792Fork a child process with a single multiplexed (i.e., not bound) thread.
5793
5794Return 0 to child process and PID of child to parent process.
5795[clinic start generated code]*/
5796
Larry Hastings2f936352014-08-05 14:04:04 +10005797static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005798os_fork1_impl(PyObject *module)
5799/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005800{
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005802
Eric Snow59032962018-09-14 14:17:20 -07005803 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5804 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5805 return NULL;
5806 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005807 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005808 pid = fork1();
5809 if (pid == 0) {
5810 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005811 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005812 } else {
5813 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005814 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 }
5816 if (pid == -1)
5817 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005819}
Larry Hastings2f936352014-08-05 14:04:04 +10005820#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005821
5822
Guido van Rossumad0ee831995-03-01 10:34:45 +00005823#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005824/*[clinic input]
5825os.fork
5826
5827Fork a child process.
5828
5829Return 0 to child process and PID of child to parent process.
5830[clinic start generated code]*/
5831
Larry Hastings2f936352014-08-05 14:04:04 +10005832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005833os_fork_impl(PyObject *module)
5834/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005835{
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005837
Eric Snow59032962018-09-14 14:17:20 -07005838 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5839 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5840 return NULL;
5841 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005842 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005843 pid = fork();
5844 if (pid == 0) {
5845 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005846 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005847 } else {
5848 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005849 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005850 }
5851 if (pid == -1)
5852 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005853 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005854}
Larry Hastings2f936352014-08-05 14:04:04 +10005855#endif /* HAVE_FORK */
5856
Guido van Rossum85e3b011991-06-03 12:42:10 +00005857
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005858#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005859#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005860/*[clinic input]
5861os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005862
Larry Hastings2f936352014-08-05 14:04:04 +10005863 policy: int
5864
5865Get the maximum scheduling priority for policy.
5866[clinic start generated code]*/
5867
Larry Hastings2f936352014-08-05 14:04:04 +10005868static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005869os_sched_get_priority_max_impl(PyObject *module, int policy)
5870/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005871{
5872 int max;
5873
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005874 max = sched_get_priority_max(policy);
5875 if (max < 0)
5876 return posix_error();
5877 return PyLong_FromLong(max);
5878}
5879
Larry Hastings2f936352014-08-05 14:04:04 +10005880
5881/*[clinic input]
5882os.sched_get_priority_min
5883
5884 policy: int
5885
5886Get the minimum scheduling priority for policy.
5887[clinic start generated code]*/
5888
Larry Hastings2f936352014-08-05 14:04:04 +10005889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005890os_sched_get_priority_min_impl(PyObject *module, int policy)
5891/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005892{
5893 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005894 if (min < 0)
5895 return posix_error();
5896 return PyLong_FromLong(min);
5897}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005898#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5899
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005900
Larry Hastings2f936352014-08-05 14:04:04 +10005901#ifdef HAVE_SCHED_SETSCHEDULER
5902/*[clinic input]
5903os.sched_getscheduler
5904 pid: pid_t
5905 /
5906
5907Get the scheduling policy for the process identifiedy by pid.
5908
5909Passing 0 for pid returns the scheduling policy for the calling process.
5910[clinic start generated code]*/
5911
Larry Hastings2f936352014-08-05 14:04:04 +10005912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005913os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5914/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005915{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005916 int policy;
5917
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005918 policy = sched_getscheduler(pid);
5919 if (policy < 0)
5920 return posix_error();
5921 return PyLong_FromLong(policy);
5922}
Larry Hastings2f936352014-08-05 14:04:04 +10005923#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005924
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005925
William Orr81574b82018-10-01 22:19:56 -07005926#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005927/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005928class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10005929
5930@classmethod
5931os.sched_param.__new__
5932
5933 sched_priority: object
5934 A scheduling parameter.
5935
5936Current has only one field: sched_priority");
5937[clinic start generated code]*/
5938
Larry Hastings2f936352014-08-05 14:04:04 +10005939static PyObject *
5940os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005941/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005942{
5943 PyObject *res;
5944
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005945 res = PyStructSequence_New(type);
5946 if (!res)
5947 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005948 Py_INCREF(sched_priority);
5949 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005950 return res;
5951}
5952
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005953
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005954PyDoc_VAR(os_sched_param__doc__);
5955
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005956static PyStructSequence_Field sched_param_fields[] = {
5957 {"sched_priority", "the scheduling priority"},
5958 {0}
5959};
5960
5961static PyStructSequence_Desc sched_param_desc = {
5962 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005963 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005964 sched_param_fields,
5965 1
5966};
5967
5968static int
5969convert_sched_param(PyObject *param, struct sched_param *res)
5970{
5971 long priority;
5972
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005973 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005974 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5975 return 0;
5976 }
5977 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5978 if (priority == -1 && PyErr_Occurred())
5979 return 0;
5980 if (priority > INT_MAX || priority < INT_MIN) {
5981 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5982 return 0;
5983 }
5984 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5985 return 1;
5986}
William Orr81574b82018-10-01 22:19:56 -07005987#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005988
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005989
5990#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005991/*[clinic input]
5992os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005993
Larry Hastings2f936352014-08-05 14:04:04 +10005994 pid: pid_t
5995 policy: int
5996 param: sched_param
5997 /
5998
5999Set the scheduling policy for the process identified by pid.
6000
6001If pid is 0, the calling process is changed.
6002param is an instance of sched_param.
6003[clinic start generated code]*/
6004
Larry Hastings2f936352014-08-05 14:04:04 +10006005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006006os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006007 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006008/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006009{
Jesus Cea9c822272011-09-10 01:40:52 +02006010 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006011 ** sched_setscheduler() returns 0 in Linux, but the previous
6012 ** scheduling policy under Solaris/Illumos, and others.
6013 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006014 */
Larry Hastings2f936352014-08-05 14:04:04 +10006015 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006016 return posix_error();
6017 Py_RETURN_NONE;
6018}
Larry Hastings2f936352014-08-05 14:04:04 +10006019#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006020
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006021
6022#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006023/*[clinic input]
6024os.sched_getparam
6025 pid: pid_t
6026 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006027
Larry Hastings2f936352014-08-05 14:04:04 +10006028Returns scheduling parameters for the process identified by pid.
6029
6030If pid is 0, returns parameters for the calling process.
6031Return value is an instance of sched_param.
6032[clinic start generated code]*/
6033
Larry Hastings2f936352014-08-05 14:04:04 +10006034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006035os_sched_getparam_impl(PyObject *module, pid_t pid)
6036/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006037{
6038 struct sched_param param;
6039 PyObject *result;
6040 PyObject *priority;
6041
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006042 if (sched_getparam(pid, &param))
6043 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006044 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006045 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006046 return NULL;
6047 priority = PyLong_FromLong(param.sched_priority);
6048 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006049 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006050 return NULL;
6051 }
Larry Hastings2f936352014-08-05 14:04:04 +10006052 PyStructSequence_SET_ITEM(result, 0, priority);
6053 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006054}
6055
Larry Hastings2f936352014-08-05 14:04:04 +10006056
6057/*[clinic input]
6058os.sched_setparam
6059 pid: pid_t
6060 param: sched_param
6061 /
6062
6063Set scheduling parameters for the process identified by pid.
6064
6065If pid is 0, sets parameters for the calling process.
6066param should be an instance of sched_param.
6067[clinic start generated code]*/
6068
Larry Hastings2f936352014-08-05 14:04:04 +10006069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006070os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006071 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006072/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006073{
6074 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006075 return posix_error();
6076 Py_RETURN_NONE;
6077}
Larry Hastings2f936352014-08-05 14:04:04 +10006078#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006079
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006080
6081#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006082/*[clinic input]
6083os.sched_rr_get_interval -> double
6084 pid: pid_t
6085 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006086
Larry Hastings2f936352014-08-05 14:04:04 +10006087Return the round-robin quantum for the process identified by pid, in seconds.
6088
6089Value returned is a float.
6090[clinic start generated code]*/
6091
Larry Hastings2f936352014-08-05 14:04:04 +10006092static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006093os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6094/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006095{
6096 struct timespec interval;
6097 if (sched_rr_get_interval(pid, &interval)) {
6098 posix_error();
6099 return -1.0;
6100 }
6101 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6102}
6103#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006104
Larry Hastings2f936352014-08-05 14:04:04 +10006105
6106/*[clinic input]
6107os.sched_yield
6108
6109Voluntarily relinquish the CPU.
6110[clinic start generated code]*/
6111
Larry Hastings2f936352014-08-05 14:04:04 +10006112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006113os_sched_yield_impl(PyObject *module)
6114/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006115{
6116 if (sched_yield())
6117 return posix_error();
6118 Py_RETURN_NONE;
6119}
6120
Benjamin Peterson2740af82011-08-02 17:41:34 -05006121#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006122/* The minimum number of CPUs allocated in a cpu_set_t */
6123static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006124
Larry Hastings2f936352014-08-05 14:04:04 +10006125/*[clinic input]
6126os.sched_setaffinity
6127 pid: pid_t
6128 mask : object
6129 /
6130
6131Set the CPU affinity of the process identified by pid to mask.
6132
6133mask should be an iterable of integers identifying CPUs.
6134[clinic start generated code]*/
6135
Larry Hastings2f936352014-08-05 14:04:04 +10006136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006137os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6138/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006139{
Antoine Pitrou84869872012-08-04 16:16:35 +02006140 int ncpus;
6141 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006142 cpu_set_t *cpu_set = NULL;
6143 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006144
Larry Hastings2f936352014-08-05 14:04:04 +10006145 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006146 if (iterator == NULL)
6147 return NULL;
6148
6149 ncpus = NCPUS_START;
6150 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006151 cpu_set = CPU_ALLOC(ncpus);
6152 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006153 PyErr_NoMemory();
6154 goto error;
6155 }
Larry Hastings2f936352014-08-05 14:04:04 +10006156 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006157
6158 while ((item = PyIter_Next(iterator))) {
6159 long cpu;
6160 if (!PyLong_Check(item)) {
6161 PyErr_Format(PyExc_TypeError,
6162 "expected an iterator of ints, "
6163 "but iterator yielded %R",
6164 Py_TYPE(item));
6165 Py_DECREF(item);
6166 goto error;
6167 }
6168 cpu = PyLong_AsLong(item);
6169 Py_DECREF(item);
6170 if (cpu < 0) {
6171 if (!PyErr_Occurred())
6172 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6173 goto error;
6174 }
6175 if (cpu > INT_MAX - 1) {
6176 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6177 goto error;
6178 }
6179 if (cpu >= ncpus) {
6180 /* Grow CPU mask to fit the CPU number */
6181 int newncpus = ncpus;
6182 cpu_set_t *newmask;
6183 size_t newsetsize;
6184 while (newncpus <= cpu) {
6185 if (newncpus > INT_MAX / 2)
6186 newncpus = cpu + 1;
6187 else
6188 newncpus = newncpus * 2;
6189 }
6190 newmask = CPU_ALLOC(newncpus);
6191 if (newmask == NULL) {
6192 PyErr_NoMemory();
6193 goto error;
6194 }
6195 newsetsize = CPU_ALLOC_SIZE(newncpus);
6196 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006197 memcpy(newmask, cpu_set, setsize);
6198 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006199 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006200 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006201 ncpus = newncpus;
6202 }
Larry Hastings2f936352014-08-05 14:04:04 +10006203 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006204 }
6205 Py_CLEAR(iterator);
6206
Larry Hastings2f936352014-08-05 14:04:04 +10006207 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006208 posix_error();
6209 goto error;
6210 }
Larry Hastings2f936352014-08-05 14:04:04 +10006211 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006212 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006213
6214error:
Larry Hastings2f936352014-08-05 14:04:04 +10006215 if (cpu_set)
6216 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006217 Py_XDECREF(iterator);
6218 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006219}
6220
Larry Hastings2f936352014-08-05 14:04:04 +10006221
6222/*[clinic input]
6223os.sched_getaffinity
6224 pid: pid_t
6225 /
6226
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006227Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006228
6229The affinity is returned as a set of CPU identifiers.
6230[clinic start generated code]*/
6231
Larry Hastings2f936352014-08-05 14:04:04 +10006232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006233os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006234/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006235{
Antoine Pitrou84869872012-08-04 16:16:35 +02006236 int cpu, ncpus, count;
6237 size_t setsize;
6238 cpu_set_t *mask = NULL;
6239 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006240
Antoine Pitrou84869872012-08-04 16:16:35 +02006241 ncpus = NCPUS_START;
6242 while (1) {
6243 setsize = CPU_ALLOC_SIZE(ncpus);
6244 mask = CPU_ALLOC(ncpus);
6245 if (mask == NULL)
6246 return PyErr_NoMemory();
6247 if (sched_getaffinity(pid, setsize, mask) == 0)
6248 break;
6249 CPU_FREE(mask);
6250 if (errno != EINVAL)
6251 return posix_error();
6252 if (ncpus > INT_MAX / 2) {
6253 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6254 "a large enough CPU set");
6255 return NULL;
6256 }
6257 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006258 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006259
6260 res = PySet_New(NULL);
6261 if (res == NULL)
6262 goto error;
6263 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6264 if (CPU_ISSET_S(cpu, setsize, mask)) {
6265 PyObject *cpu_num = PyLong_FromLong(cpu);
6266 --count;
6267 if (cpu_num == NULL)
6268 goto error;
6269 if (PySet_Add(res, cpu_num)) {
6270 Py_DECREF(cpu_num);
6271 goto error;
6272 }
6273 Py_DECREF(cpu_num);
6274 }
6275 }
6276 CPU_FREE(mask);
6277 return res;
6278
6279error:
6280 if (mask)
6281 CPU_FREE(mask);
6282 Py_XDECREF(res);
6283 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006284}
6285
Benjamin Peterson2740af82011-08-02 17:41:34 -05006286#endif /* HAVE_SCHED_SETAFFINITY */
6287
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006288#endif /* HAVE_SCHED_H */
6289
Larry Hastings2f936352014-08-05 14:04:04 +10006290
Neal Norwitzb59798b2003-03-21 01:43:31 +00006291/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006292/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6293#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006294#define DEV_PTY_FILE "/dev/ptc"
6295#define HAVE_DEV_PTMX
6296#else
6297#define DEV_PTY_FILE "/dev/ptmx"
6298#endif
6299
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006300#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006301#ifdef HAVE_PTY_H
6302#include <pty.h>
6303#else
6304#ifdef HAVE_LIBUTIL_H
6305#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006306#else
6307#ifdef HAVE_UTIL_H
6308#include <util.h>
6309#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006310#endif /* HAVE_LIBUTIL_H */
6311#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006312#ifdef HAVE_STROPTS_H
6313#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006314#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006315#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006316
Larry Hastings2f936352014-08-05 14:04:04 +10006317
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006318#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006319/*[clinic input]
6320os.openpty
6321
6322Open a pseudo-terminal.
6323
6324Return a tuple of (master_fd, slave_fd) containing open file descriptors
6325for both the master and slave ends.
6326[clinic start generated code]*/
6327
Larry Hastings2f936352014-08-05 14:04:04 +10006328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006329os_openpty_impl(PyObject *module)
6330/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006331{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006332 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006333#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006334 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006335#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006336#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006338#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006340#endif
6341#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006342
Thomas Wouters70c21a12000-07-14 14:28:33 +00006343#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006345 goto posix_error;
6346
6347 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6348 goto error;
6349 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6350 goto error;
6351
Neal Norwitzb59798b2003-03-21 01:43:31 +00006352#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6354 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006355 goto posix_error;
6356 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6357 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006358
Victor Stinnerdaf45552013-08-28 00:53:59 +02006359 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006360 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006361 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006362
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006363#else
Victor Stinner000de532013-11-25 23:19:58 +01006364 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006366 goto posix_error;
6367
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006369
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 /* change permission of slave */
6371 if (grantpt(master_fd) < 0) {
6372 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006373 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006374 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006375
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 /* unlock slave */
6377 if (unlockpt(master_fd) < 0) {
6378 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006379 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006381
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006383
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 slave_name = ptsname(master_fd); /* get name of slave */
6385 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006386 goto posix_error;
6387
6388 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006389 if (slave_fd == -1)
6390 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006391
6392 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6393 goto posix_error;
6394
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006395#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6397 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006398#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006400#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006401#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006402#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006403
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006405
Victor Stinnerdaf45552013-08-28 00:53:59 +02006406posix_error:
6407 posix_error();
6408error:
6409 if (master_fd != -1)
6410 close(master_fd);
6411 if (slave_fd != -1)
6412 close(slave_fd);
6413 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006414}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006415#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006416
Larry Hastings2f936352014-08-05 14:04:04 +10006417
Fred Drake8cef4cf2000-06-28 16:40:38 +00006418#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006419/*[clinic input]
6420os.forkpty
6421
6422Fork a new process with a new pseudo-terminal as controlling tty.
6423
6424Returns a tuple of (pid, master_fd).
6425Like fork(), return pid of 0 to the child process,
6426and pid of child to the parent process.
6427To both, return fd of newly opened pseudo-terminal.
6428[clinic start generated code]*/
6429
Larry Hastings2f936352014-08-05 14:04:04 +10006430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006431os_forkpty_impl(PyObject *module)
6432/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006433{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006434 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006436
Eric Snow59032962018-09-14 14:17:20 -07006437 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6438 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6439 return NULL;
6440 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006441 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 pid = forkpty(&master_fd, NULL, NULL, NULL);
6443 if (pid == 0) {
6444 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006445 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 } else {
6447 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006448 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 }
6450 if (pid == -1)
6451 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006453}
Larry Hastings2f936352014-08-05 14:04:04 +10006454#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006455
Ross Lagerwall7807c352011-03-17 20:20:30 +02006456
Guido van Rossumad0ee831995-03-01 10:34:45 +00006457#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006458/*[clinic input]
6459os.getegid
6460
6461Return the current process's effective group id.
6462[clinic start generated code]*/
6463
Larry Hastings2f936352014-08-05 14:04:04 +10006464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006465os_getegid_impl(PyObject *module)
6466/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006467{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006468 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006469}
Larry Hastings2f936352014-08-05 14:04:04 +10006470#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Guido van Rossumad0ee831995-03-01 10:34:45 +00006473#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006474/*[clinic input]
6475os.geteuid
6476
6477Return the current process's effective user id.
6478[clinic start generated code]*/
6479
Larry Hastings2f936352014-08-05 14:04:04 +10006480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006481os_geteuid_impl(PyObject *module)
6482/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006483{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006484 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006485}
Larry Hastings2f936352014-08-05 14:04:04 +10006486#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006488
Guido van Rossumad0ee831995-03-01 10:34:45 +00006489#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006490/*[clinic input]
6491os.getgid
6492
6493Return the current process's group id.
6494[clinic start generated code]*/
6495
Larry Hastings2f936352014-08-05 14:04:04 +10006496static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006497os_getgid_impl(PyObject *module)
6498/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006499{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006500 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006501}
Larry Hastings2f936352014-08-05 14:04:04 +10006502#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Berker Peksag39404992016-09-15 20:45:16 +03006505#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006506/*[clinic input]
6507os.getpid
6508
6509Return the current process id.
6510[clinic start generated code]*/
6511
Larry Hastings2f936352014-08-05 14:04:04 +10006512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006513os_getpid_impl(PyObject *module)
6514/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006515{
Victor Stinner8c62be82010-05-06 00:08:46 +00006516 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006517}
Berker Peksag39404992016-09-15 20:45:16 +03006518#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006519
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006520#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006521
6522/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006523PyDoc_STRVAR(posix_getgrouplist__doc__,
6524"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6525Returns a list of groups to which a user belongs.\n\n\
6526 user: username to lookup\n\
6527 group: base group id of the user");
6528
6529static PyObject *
6530posix_getgrouplist(PyObject *self, PyObject *args)
6531{
6532#ifdef NGROUPS_MAX
6533#define MAX_GROUPS NGROUPS_MAX
6534#else
6535 /* defined to be 16 on Solaris7, so this should be a small number */
6536#define MAX_GROUPS 64
6537#endif
6538
6539 const char *user;
6540 int i, ngroups;
6541 PyObject *list;
6542#ifdef __APPLE__
6543 int *groups, basegid;
6544#else
6545 gid_t *groups, basegid;
6546#endif
6547 ngroups = MAX_GROUPS;
6548
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006549#ifdef __APPLE__
6550 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006551 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006552#else
6553 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6554 _Py_Gid_Converter, &basegid))
6555 return NULL;
6556#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006557
6558#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006559 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006560#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006561 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006562#endif
6563 if (groups == NULL)
6564 return PyErr_NoMemory();
6565
6566 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6567 PyMem_Del(groups);
6568 return posix_error();
6569 }
6570
6571 list = PyList_New(ngroups);
6572 if (list == NULL) {
6573 PyMem_Del(groups);
6574 return NULL;
6575 }
6576
6577 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006578#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006579 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006580#else
6581 PyObject *o = _PyLong_FromGid(groups[i]);
6582#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006583 if (o == NULL) {
6584 Py_DECREF(list);
6585 PyMem_Del(groups);
6586 return NULL;
6587 }
6588 PyList_SET_ITEM(list, i, o);
6589 }
6590
6591 PyMem_Del(groups);
6592
6593 return list;
6594}
Larry Hastings2f936352014-08-05 14:04:04 +10006595#endif /* HAVE_GETGROUPLIST */
6596
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006597
Fred Drakec9680921999-12-13 16:37:25 +00006598#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006599/*[clinic input]
6600os.getgroups
6601
6602Return list of supplemental group IDs for the process.
6603[clinic start generated code]*/
6604
Larry Hastings2f936352014-08-05 14:04:04 +10006605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006606os_getgroups_impl(PyObject *module)
6607/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006608{
6609 PyObject *result = NULL;
6610
Fred Drakec9680921999-12-13 16:37:25 +00006611#ifdef NGROUPS_MAX
6612#define MAX_GROUPS NGROUPS_MAX
6613#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006615#define MAX_GROUPS 64
6616#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006618
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006619 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006620 * This is a helper variable to store the intermediate result when
6621 * that happens.
6622 *
6623 * To keep the code readable the OSX behaviour is unconditional,
6624 * according to the POSIX spec this should be safe on all unix-y
6625 * systems.
6626 */
6627 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006629
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006630#ifdef __APPLE__
6631 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6632 * there are more groups than can fit in grouplist. Therefore, on OS X
6633 * always first call getgroups with length 0 to get the actual number
6634 * of groups.
6635 */
6636 n = getgroups(0, NULL);
6637 if (n < 0) {
6638 return posix_error();
6639 } else if (n <= MAX_GROUPS) {
6640 /* groups will fit in existing array */
6641 alt_grouplist = grouplist;
6642 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006643 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006644 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006645 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006646 }
6647 }
6648
6649 n = getgroups(n, alt_grouplist);
6650 if (n == -1) {
6651 if (alt_grouplist != grouplist) {
6652 PyMem_Free(alt_grouplist);
6653 }
6654 return posix_error();
6655 }
6656#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006658 if (n < 0) {
6659 if (errno == EINVAL) {
6660 n = getgroups(0, NULL);
6661 if (n == -1) {
6662 return posix_error();
6663 }
6664 if (n == 0) {
6665 /* Avoid malloc(0) */
6666 alt_grouplist = grouplist;
6667 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006668 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006669 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006670 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006671 }
6672 n = getgroups(n, alt_grouplist);
6673 if (n == -1) {
6674 PyMem_Free(alt_grouplist);
6675 return posix_error();
6676 }
6677 }
6678 } else {
6679 return posix_error();
6680 }
6681 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006682#endif
6683
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006684 result = PyList_New(n);
6685 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 int i;
6687 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006688 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006690 Py_DECREF(result);
6691 result = NULL;
6692 break;
Fred Drakec9680921999-12-13 16:37:25 +00006693 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006695 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006696 }
6697
6698 if (alt_grouplist != grouplist) {
6699 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006701
Fred Drakec9680921999-12-13 16:37:25 +00006702 return result;
6703}
Larry Hastings2f936352014-08-05 14:04:04 +10006704#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006705
Antoine Pitroub7572f02009-12-02 20:46:48 +00006706#ifdef HAVE_INITGROUPS
6707PyDoc_STRVAR(posix_initgroups__doc__,
6708"initgroups(username, gid) -> None\n\n\
6709Call the system initgroups() to initialize the group access list with all of\n\
6710the groups of which the specified username is a member, plus the specified\n\
6711group id.");
6712
Larry Hastings2f936352014-08-05 14:04:04 +10006713/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006714static PyObject *
6715posix_initgroups(PyObject *self, PyObject *args)
6716{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006717 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006718 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006719 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006720#ifdef __APPLE__
6721 int gid;
6722#else
6723 gid_t gid;
6724#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006725
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006726#ifdef __APPLE__
6727 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6728 PyUnicode_FSConverter, &oname,
6729 &gid))
6730#else
6731 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6732 PyUnicode_FSConverter, &oname,
6733 _Py_Gid_Converter, &gid))
6734#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006736 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006737
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006738 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006739 Py_DECREF(oname);
6740 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006741 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006742
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006743 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006744}
Larry Hastings2f936352014-08-05 14:04:04 +10006745#endif /* HAVE_INITGROUPS */
6746
Antoine Pitroub7572f02009-12-02 20:46:48 +00006747
Martin v. Löwis606edc12002-06-13 21:09:11 +00006748#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006749/*[clinic input]
6750os.getpgid
6751
6752 pid: pid_t
6753
6754Call the system call getpgid(), and return the result.
6755[clinic start generated code]*/
6756
Larry Hastings2f936352014-08-05 14:04:04 +10006757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006758os_getpgid_impl(PyObject *module, pid_t pid)
6759/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006760{
6761 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 if (pgid < 0)
6763 return posix_error();
6764 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006765}
6766#endif /* HAVE_GETPGID */
6767
6768
Guido van Rossumb6775db1994-08-01 11:34:53 +00006769#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006770/*[clinic input]
6771os.getpgrp
6772
6773Return the current process group id.
6774[clinic start generated code]*/
6775
Larry Hastings2f936352014-08-05 14:04:04 +10006776static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006777os_getpgrp_impl(PyObject *module)
6778/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006779{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006780#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006782#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006784#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006785}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006786#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006788
Guido van Rossumb6775db1994-08-01 11:34:53 +00006789#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006790/*[clinic input]
6791os.setpgrp
6792
6793Make the current process the leader of its process group.
6794[clinic start generated code]*/
6795
Larry Hastings2f936352014-08-05 14:04:04 +10006796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006797os_setpgrp_impl(PyObject *module)
6798/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006799{
Guido van Rossum64933891994-10-20 21:56:42 +00006800#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006802#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006804#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006806 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006807}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006808#endif /* HAVE_SETPGRP */
6809
Guido van Rossumad0ee831995-03-01 10:34:45 +00006810#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006811
6812#ifdef MS_WINDOWS
6813#include <tlhelp32.h>
6814
6815static PyObject*
6816win32_getppid()
6817{
6818 HANDLE snapshot;
6819 pid_t mypid;
6820 PyObject* result = NULL;
6821 BOOL have_record;
6822 PROCESSENTRY32 pe;
6823
6824 mypid = getpid(); /* This function never fails */
6825
6826 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6827 if (snapshot == INVALID_HANDLE_VALUE)
6828 return PyErr_SetFromWindowsErr(GetLastError());
6829
6830 pe.dwSize = sizeof(pe);
6831 have_record = Process32First(snapshot, &pe);
6832 while (have_record) {
6833 if (mypid == (pid_t)pe.th32ProcessID) {
6834 /* We could cache the ulong value in a static variable. */
6835 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6836 break;
6837 }
6838
6839 have_record = Process32Next(snapshot, &pe);
6840 }
6841
6842 /* If our loop exits and our pid was not found (result will be NULL)
6843 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6844 * error anyway, so let's raise it. */
6845 if (!result)
6846 result = PyErr_SetFromWindowsErr(GetLastError());
6847
6848 CloseHandle(snapshot);
6849
6850 return result;
6851}
6852#endif /*MS_WINDOWS*/
6853
Larry Hastings2f936352014-08-05 14:04:04 +10006854
6855/*[clinic input]
6856os.getppid
6857
6858Return the parent's process id.
6859
6860If the parent process has already exited, Windows machines will still
6861return its id; others systems will return the id of the 'init' process (1).
6862[clinic start generated code]*/
6863
Larry Hastings2f936352014-08-05 14:04:04 +10006864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006865os_getppid_impl(PyObject *module)
6866/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006867{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006868#ifdef MS_WINDOWS
6869 return win32_getppid();
6870#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006872#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006873}
6874#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006876
Fred Drake12c6e2d1999-12-14 21:25:03 +00006877#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006878/*[clinic input]
6879os.getlogin
6880
6881Return the actual login name.
6882[clinic start generated code]*/
6883
Larry Hastings2f936352014-08-05 14:04:04 +10006884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006885os_getlogin_impl(PyObject *module)
6886/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006887{
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006889#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006890 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006891 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006892
6893 if (GetUserNameW(user_name, &num_chars)) {
6894 /* num_chars is the number of unicode chars plus null terminator */
6895 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006896 }
6897 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006898 result = PyErr_SetFromWindowsErr(GetLastError());
6899#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006900 char *name;
6901 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006902
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 errno = 0;
6904 name = getlogin();
6905 if (name == NULL) {
6906 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006907 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006908 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006909 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 }
6911 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006912 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006914#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006915 return result;
6916}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006917#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006918
Larry Hastings2f936352014-08-05 14:04:04 +10006919
Guido van Rossumad0ee831995-03-01 10:34:45 +00006920#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006921/*[clinic input]
6922os.getuid
6923
6924Return the current process's user id.
6925[clinic start generated code]*/
6926
Larry Hastings2f936352014-08-05 14:04:04 +10006927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006928os_getuid_impl(PyObject *module)
6929/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006930{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006931 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006932}
Larry Hastings2f936352014-08-05 14:04:04 +10006933#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006934
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006935
Brian Curtineb24d742010-04-12 17:16:38 +00006936#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006937#define HAVE_KILL
6938#endif /* MS_WINDOWS */
6939
6940#ifdef HAVE_KILL
6941/*[clinic input]
6942os.kill
6943
6944 pid: pid_t
6945 signal: Py_ssize_t
6946 /
6947
6948Kill a process with a signal.
6949[clinic start generated code]*/
6950
Larry Hastings2f936352014-08-05 14:04:04 +10006951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006952os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6953/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006954#ifndef MS_WINDOWS
6955{
6956 if (kill(pid, (int)signal) == -1)
6957 return posix_error();
6958 Py_RETURN_NONE;
6959}
6960#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006961{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006962 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006963 DWORD sig = (DWORD)signal;
6964 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006966
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 /* Console processes which share a common console can be sent CTRL+C or
6968 CTRL+BREAK events, provided they handle said events. */
6969 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006970 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 err = GetLastError();
6972 PyErr_SetFromWindowsErr(err);
6973 }
6974 else
6975 Py_RETURN_NONE;
6976 }
Brian Curtineb24d742010-04-12 17:16:38 +00006977
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6979 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006980 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006981 if (handle == NULL) {
6982 err = GetLastError();
6983 return PyErr_SetFromWindowsErr(err);
6984 }
Brian Curtineb24d742010-04-12 17:16:38 +00006985
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 if (TerminateProcess(handle, sig) == 0) {
6987 err = GetLastError();
6988 result = PyErr_SetFromWindowsErr(err);
6989 } else {
6990 Py_INCREF(Py_None);
6991 result = Py_None;
6992 }
Brian Curtineb24d742010-04-12 17:16:38 +00006993
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 CloseHandle(handle);
6995 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006996}
Larry Hastings2f936352014-08-05 14:04:04 +10006997#endif /* !MS_WINDOWS */
6998#endif /* HAVE_KILL */
6999
7000
7001#ifdef HAVE_KILLPG
7002/*[clinic input]
7003os.killpg
7004
7005 pgid: pid_t
7006 signal: int
7007 /
7008
7009Kill a process group with a signal.
7010[clinic start generated code]*/
7011
Larry Hastings2f936352014-08-05 14:04:04 +10007012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007013os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7014/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007015{
7016 /* XXX some man pages make the `pgid` parameter an int, others
7017 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7018 take the same type. Moreover, pid_t is always at least as wide as
7019 int (else compilation of this module fails), which is safe. */
7020 if (killpg(pgid, signal) == -1)
7021 return posix_error();
7022 Py_RETURN_NONE;
7023}
7024#endif /* HAVE_KILLPG */
7025
Brian Curtineb24d742010-04-12 17:16:38 +00007026
Guido van Rossumc0125471996-06-28 18:55:32 +00007027#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007028#ifdef HAVE_SYS_LOCK_H
7029#include <sys/lock.h>
7030#endif
7031
Larry Hastings2f936352014-08-05 14:04:04 +10007032/*[clinic input]
7033os.plock
7034 op: int
7035 /
7036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007037Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007038[clinic start generated code]*/
7039
Larry Hastings2f936352014-08-05 14:04:04 +10007040static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007041os_plock_impl(PyObject *module, int op)
7042/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007043{
Victor Stinner8c62be82010-05-06 00:08:46 +00007044 if (plock(op) == -1)
7045 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007046 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007047}
Larry Hastings2f936352014-08-05 14:04:04 +10007048#endif /* HAVE_PLOCK */
7049
Guido van Rossumc0125471996-06-28 18:55:32 +00007050
Guido van Rossumb6775db1994-08-01 11:34:53 +00007051#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007052/*[clinic input]
7053os.setuid
7054
7055 uid: uid_t
7056 /
7057
7058Set the current process's user id.
7059[clinic start generated code]*/
7060
Larry Hastings2f936352014-08-05 14:04:04 +10007061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007062os_setuid_impl(PyObject *module, uid_t uid)
7063/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007064{
Victor Stinner8c62be82010-05-06 00:08:46 +00007065 if (setuid(uid) < 0)
7066 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007067 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007068}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007069#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007070
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007071
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007072#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007073/*[clinic input]
7074os.seteuid
7075
7076 euid: uid_t
7077 /
7078
7079Set the current process's effective user id.
7080[clinic start generated code]*/
7081
Larry Hastings2f936352014-08-05 14:04:04 +10007082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007083os_seteuid_impl(PyObject *module, uid_t euid)
7084/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007085{
7086 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007088 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007089}
7090#endif /* HAVE_SETEUID */
7091
Larry Hastings2f936352014-08-05 14:04:04 +10007092
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007093#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007094/*[clinic input]
7095os.setegid
7096
7097 egid: gid_t
7098 /
7099
7100Set the current process's effective group id.
7101[clinic start generated code]*/
7102
Larry Hastings2f936352014-08-05 14:04:04 +10007103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007104os_setegid_impl(PyObject *module, gid_t egid)
7105/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007106{
7107 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007109 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007110}
7111#endif /* HAVE_SETEGID */
7112
Larry Hastings2f936352014-08-05 14:04:04 +10007113
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007114#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007115/*[clinic input]
7116os.setreuid
7117
7118 ruid: uid_t
7119 euid: uid_t
7120 /
7121
7122Set the current process's real and effective user ids.
7123[clinic start generated code]*/
7124
Larry Hastings2f936352014-08-05 14:04:04 +10007125static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007126os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7127/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007128{
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 if (setreuid(ruid, euid) < 0) {
7130 return posix_error();
7131 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007132 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007134}
7135#endif /* HAVE_SETREUID */
7136
Larry Hastings2f936352014-08-05 14:04:04 +10007137
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007138#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007139/*[clinic input]
7140os.setregid
7141
7142 rgid: gid_t
7143 egid: gid_t
7144 /
7145
7146Set the current process's real and effective group ids.
7147[clinic start generated code]*/
7148
Larry Hastings2f936352014-08-05 14:04:04 +10007149static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007150os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7151/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007152{
7153 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007154 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007155 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007156}
7157#endif /* HAVE_SETREGID */
7158
Larry Hastings2f936352014-08-05 14:04:04 +10007159
Guido van Rossumb6775db1994-08-01 11:34:53 +00007160#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007161/*[clinic input]
7162os.setgid
7163 gid: gid_t
7164 /
7165
7166Set the current process's group id.
7167[clinic start generated code]*/
7168
Larry Hastings2f936352014-08-05 14:04:04 +10007169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007170os_setgid_impl(PyObject *module, gid_t gid)
7171/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007172{
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 if (setgid(gid) < 0)
7174 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007175 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007176}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007177#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007178
Larry Hastings2f936352014-08-05 14:04:04 +10007179
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007180#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007181/*[clinic input]
7182os.setgroups
7183
7184 groups: object
7185 /
7186
7187Set the groups of the current process to list.
7188[clinic start generated code]*/
7189
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007190static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007191os_setgroups(PyObject *module, PyObject *groups)
7192/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007193{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007194 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007196
Victor Stinner8c62be82010-05-06 00:08:46 +00007197 if (!PySequence_Check(groups)) {
7198 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7199 return NULL;
7200 }
7201 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007202 if (len < 0) {
7203 return NULL;
7204 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 if (len > MAX_GROUPS) {
7206 PyErr_SetString(PyExc_ValueError, "too many groups");
7207 return NULL;
7208 }
7209 for(i = 0; i < len; i++) {
7210 PyObject *elem;
7211 elem = PySequence_GetItem(groups, i);
7212 if (!elem)
7213 return NULL;
7214 if (!PyLong_Check(elem)) {
7215 PyErr_SetString(PyExc_TypeError,
7216 "groups must be integers");
7217 Py_DECREF(elem);
7218 return NULL;
7219 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007220 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007221 Py_DECREF(elem);
7222 return NULL;
7223 }
7224 }
7225 Py_DECREF(elem);
7226 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007227
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 if (setgroups(len, grouplist) < 0)
7229 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007230 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007231}
7232#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007233
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007234#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7235static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007236wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007237{
Victor Stinner8c62be82010-05-06 00:08:46 +00007238 PyObject *result;
7239 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007240 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007241
Victor Stinner8c62be82010-05-06 00:08:46 +00007242 if (pid == -1)
7243 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007244
Victor Stinner8c62be82010-05-06 00:08:46 +00007245 if (struct_rusage == NULL) {
7246 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7247 if (m == NULL)
7248 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007249 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007250 Py_DECREF(m);
7251 if (struct_rusage == NULL)
7252 return NULL;
7253 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007254
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7256 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7257 if (!result)
7258 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007259
7260#ifndef doubletime
7261#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7262#endif
7263
Victor Stinner8c62be82010-05-06 00:08:46 +00007264 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007265 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007266 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007267 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007268#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007269 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7270 SET_INT(result, 2, ru->ru_maxrss);
7271 SET_INT(result, 3, ru->ru_ixrss);
7272 SET_INT(result, 4, ru->ru_idrss);
7273 SET_INT(result, 5, ru->ru_isrss);
7274 SET_INT(result, 6, ru->ru_minflt);
7275 SET_INT(result, 7, ru->ru_majflt);
7276 SET_INT(result, 8, ru->ru_nswap);
7277 SET_INT(result, 9, ru->ru_inblock);
7278 SET_INT(result, 10, ru->ru_oublock);
7279 SET_INT(result, 11, ru->ru_msgsnd);
7280 SET_INT(result, 12, ru->ru_msgrcv);
7281 SET_INT(result, 13, ru->ru_nsignals);
7282 SET_INT(result, 14, ru->ru_nvcsw);
7283 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007284#undef SET_INT
7285
Victor Stinner8c62be82010-05-06 00:08:46 +00007286 if (PyErr_Occurred()) {
7287 Py_DECREF(result);
7288 return NULL;
7289 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007290
Victor Stinner8c62be82010-05-06 00:08:46 +00007291 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007292}
7293#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7294
Larry Hastings2f936352014-08-05 14:04:04 +10007295
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007296#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007297/*[clinic input]
7298os.wait3
7299
7300 options: int
7301Wait for completion of a child process.
7302
7303Returns a tuple of information about the child process:
7304 (pid, status, rusage)
7305[clinic start generated code]*/
7306
Larry Hastings2f936352014-08-05 14:04:04 +10007307static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007308os_wait3_impl(PyObject *module, int options)
7309/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007310{
Victor Stinner8c62be82010-05-06 00:08:46 +00007311 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007313 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007314 WAIT_TYPE status;
7315 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007316
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007317 do {
7318 Py_BEGIN_ALLOW_THREADS
7319 pid = wait3(&status, options, &ru);
7320 Py_END_ALLOW_THREADS
7321 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7322 if (pid < 0)
7323 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007324
Victor Stinner4195b5c2012-02-08 23:03:19 +01007325 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007326}
7327#endif /* HAVE_WAIT3 */
7328
Larry Hastings2f936352014-08-05 14:04:04 +10007329
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007330#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007331/*[clinic input]
7332
7333os.wait4
7334
7335 pid: pid_t
7336 options: int
7337
7338Wait for completion of a specific child process.
7339
7340Returns a tuple of information about the child process:
7341 (pid, status, rusage)
7342[clinic start generated code]*/
7343
Larry Hastings2f936352014-08-05 14:04:04 +10007344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007345os_wait4_impl(PyObject *module, pid_t pid, int options)
7346/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007347{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007348 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007349 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007350 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 WAIT_TYPE status;
7352 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007353
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007354 do {
7355 Py_BEGIN_ALLOW_THREADS
7356 res = wait4(pid, &status, options, &ru);
7357 Py_END_ALLOW_THREADS
7358 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7359 if (res < 0)
7360 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007361
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007362 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007363}
7364#endif /* HAVE_WAIT4 */
7365
Larry Hastings2f936352014-08-05 14:04:04 +10007366
Ross Lagerwall7807c352011-03-17 20:20:30 +02007367#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007368/*[clinic input]
7369os.waitid
7370
7371 idtype: idtype_t
7372 Must be one of be P_PID, P_PGID or P_ALL.
7373 id: id_t
7374 The id to wait on.
7375 options: int
7376 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7377 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7378 /
7379
7380Returns the result of waiting for a process or processes.
7381
7382Returns either waitid_result or None if WNOHANG is specified and there are
7383no children in a waitable state.
7384[clinic start generated code]*/
7385
Larry Hastings2f936352014-08-05 14:04:04 +10007386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007387os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7388/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007389{
7390 PyObject *result;
7391 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007392 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007393 siginfo_t si;
7394 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007395
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007396 do {
7397 Py_BEGIN_ALLOW_THREADS
7398 res = waitid(idtype, id, &si, options);
7399 Py_END_ALLOW_THREADS
7400 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7401 if (res < 0)
7402 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007403
7404 if (si.si_pid == 0)
7405 Py_RETURN_NONE;
7406
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007407 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007408 if (!result)
7409 return NULL;
7410
7411 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007412 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007413 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7414 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7415 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7416 if (PyErr_Occurred()) {
7417 Py_DECREF(result);
7418 return NULL;
7419 }
7420
7421 return result;
7422}
Larry Hastings2f936352014-08-05 14:04:04 +10007423#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007424
Larry Hastings2f936352014-08-05 14:04:04 +10007425
7426#if defined(HAVE_WAITPID)
7427/*[clinic input]
7428os.waitpid
7429 pid: pid_t
7430 options: int
7431 /
7432
7433Wait for completion of a given child process.
7434
7435Returns a tuple of information regarding the child process:
7436 (pid, status)
7437
7438The options argument is ignored on Windows.
7439[clinic start generated code]*/
7440
Larry Hastings2f936352014-08-05 14:04:04 +10007441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007442os_waitpid_impl(PyObject *module, pid_t pid, int options)
7443/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007444{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007445 pid_t res;
7446 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007447 WAIT_TYPE status;
7448 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007449
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007450 do {
7451 Py_BEGIN_ALLOW_THREADS
7452 res = waitpid(pid, &status, options);
7453 Py_END_ALLOW_THREADS
7454 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7455 if (res < 0)
7456 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007457
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007458 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007459}
Tim Petersab034fa2002-02-01 11:27:43 +00007460#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007461/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007462/*[clinic input]
7463os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007464 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007465 options: int
7466 /
7467
7468Wait for completion of a given process.
7469
7470Returns a tuple of information regarding the process:
7471 (pid, status << 8)
7472
7473The options argument is ignored on Windows.
7474[clinic start generated code]*/
7475
Larry Hastings2f936352014-08-05 14:04:04 +10007476static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007477os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007478/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007479{
7480 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007481 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007482 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007483
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007484 do {
7485 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007486 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007487 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007488 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007489 Py_END_ALLOW_THREADS
7490 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007491 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007492 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007493
Victor Stinner8c62be82010-05-06 00:08:46 +00007494 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007495 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007496}
Larry Hastings2f936352014-08-05 14:04:04 +10007497#endif
7498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007499
Guido van Rossumad0ee831995-03-01 10:34:45 +00007500#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007501/*[clinic input]
7502os.wait
7503
7504Wait for completion of a child process.
7505
7506Returns a tuple of information about the child process:
7507 (pid, status)
7508[clinic start generated code]*/
7509
Larry Hastings2f936352014-08-05 14:04:04 +10007510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007511os_wait_impl(PyObject *module)
7512/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007513{
Victor Stinner8c62be82010-05-06 00:08:46 +00007514 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007515 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007516 WAIT_TYPE status;
7517 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007518
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007519 do {
7520 Py_BEGIN_ALLOW_THREADS
7521 pid = wait(&status);
7522 Py_END_ALLOW_THREADS
7523 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7524 if (pid < 0)
7525 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007526
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007528}
Larry Hastings2f936352014-08-05 14:04:04 +10007529#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007530
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007531
Larry Hastings9cf065c2012-06-22 16:30:09 -07007532#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007533/*[clinic input]
7534os.readlink
7535
7536 path: path_t
7537 *
7538 dir_fd: dir_fd(requires='readlinkat') = None
7539
7540Return a string representing the path to which the symbolic link points.
7541
7542If dir_fd is not None, it should be a file descriptor open to a directory,
7543and path should be relative; path will then be relative to that directory.
7544
7545dir_fd may not be implemented on your platform. If it is unavailable,
7546using it will raise a NotImplementedError.
7547[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007548
Barry Warsaw53699e91996-12-10 23:23:01 +00007549static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007550os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7551/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007552{
Berker Peksage0b5b202018-08-15 13:03:41 +03007553#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007554 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007555 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007556
7557 Py_BEGIN_ALLOW_THREADS
7558#ifdef HAVE_READLINKAT
7559 if (dir_fd != DEFAULT_DIR_FD)
7560 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7561 else
7562#endif
7563 length = readlink(path->narrow, buffer, MAXPATHLEN);
7564 Py_END_ALLOW_THREADS
7565
7566 if (length < 0) {
7567 return path_error(path);
7568 }
7569 buffer[length] = '\0';
7570
7571 if (PyUnicode_Check(path->object))
7572 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7573 else
7574 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007575#elif defined(MS_WINDOWS)
7576 DWORD n_bytes_returned;
7577 DWORD io_result;
7578 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007579 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7580 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7581 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007582 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007583
Larry Hastings2f936352014-08-05 14:04:04 +10007584 /* First get a handle to the reparse point */
7585 Py_BEGIN_ALLOW_THREADS
7586 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007587 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007588 0,
7589 0,
7590 0,
7591 OPEN_EXISTING,
7592 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7593 0);
7594 Py_END_ALLOW_THREADS
7595
Berker Peksage0b5b202018-08-15 13:03:41 +03007596 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007597 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007598 }
Larry Hastings2f936352014-08-05 14:04:04 +10007599
7600 Py_BEGIN_ALLOW_THREADS
7601 /* New call DeviceIoControl to read the reparse point */
7602 io_result = DeviceIoControl(
7603 reparse_point_handle,
7604 FSCTL_GET_REPARSE_POINT,
7605 0, 0, /* in buffer */
7606 target_buffer, sizeof(target_buffer),
7607 &n_bytes_returned,
7608 0 /* we're not using OVERLAPPED_IO */
7609 );
7610 CloseHandle(reparse_point_handle);
7611 Py_END_ALLOW_THREADS
7612
Berker Peksage0b5b202018-08-15 13:03:41 +03007613 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007614 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007615 }
Larry Hastings2f936352014-08-05 14:04:04 +10007616
7617 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7618 {
7619 PyErr_SetString(PyExc_ValueError,
7620 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007621 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007622 }
SSE43c34aad2018-02-13 00:10:35 +07007623 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7624 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007625
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007626 result = PyUnicode_FromWideChar(print_name,
7627 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7628 if (path->narrow) {
7629 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007630 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007631 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007632#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007633}
Berker Peksage0b5b202018-08-15 13:03:41 +03007634#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007635
Larry Hastings9cf065c2012-06-22 16:30:09 -07007636#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007637
7638#if defined(MS_WINDOWS)
7639
7640/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Steve Dower6921e732018-03-05 14:26:08 -08007641static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007642
Larry Hastings9cf065c2012-06-22 16:30:09 -07007643static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007644check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007645{
7646 HINSTANCE hKernel32;
7647 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007648 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007649 return 1;
7650 hKernel32 = GetModuleHandleW(L"KERNEL32");
7651 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7652 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007653 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007654}
7655
Steve Dower6921e732018-03-05 14:26:08 -08007656/* Remove the last portion of the path - return 0 on success */
7657static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007658_dirnameW(WCHAR *path)
7659{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007660 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007661 size_t length = wcsnlen_s(path, MAX_PATH);
7662 if (length == MAX_PATH) {
7663 return -1;
7664 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007665
7666 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007667 for(ptr = path + length; ptr != path; ptr--) {
7668 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007669 break;
Steve Dower6921e732018-03-05 14:26:08 -08007670 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007671 }
7672 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007673 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007674}
7675
Victor Stinner31b3b922013-06-05 01:49:17 +02007676/* Is this path absolute? */
7677static int
7678_is_absW(const WCHAR *path)
7679{
Steve Dower6921e732018-03-05 14:26:08 -08007680 return path[0] == L'\\' || path[0] == L'/' ||
7681 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007682}
7683
Steve Dower6921e732018-03-05 14:26:08 -08007684/* join root and rest with a backslash - return 0 on success */
7685static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007686_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7687{
Victor Stinner31b3b922013-06-05 01:49:17 +02007688 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007689 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007690 }
7691
Steve Dower6921e732018-03-05 14:26:08 -08007692 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7693 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007694 }
Steve Dower6921e732018-03-05 14:26:08 -08007695
7696 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7697 return -1;
7698 }
7699
7700 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007701}
7702
Victor Stinner31b3b922013-06-05 01:49:17 +02007703/* Return True if the path at src relative to dest is a directory */
7704static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007705_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007706{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007707 WIN32_FILE_ATTRIBUTE_DATA src_info;
7708 WCHAR dest_parent[MAX_PATH];
7709 WCHAR src_resolved[MAX_PATH] = L"";
7710
7711 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007712 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7713 _dirnameW(dest_parent)) {
7714 return 0;
7715 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007716 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007717 if (_joinW(src_resolved, dest_parent, src)) {
7718 return 0;
7719 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007720 return (
7721 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7722 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7723 );
7724}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007725#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007726
Larry Hastings2f936352014-08-05 14:04:04 +10007727
7728/*[clinic input]
7729os.symlink
7730 src: path_t
7731 dst: path_t
7732 target_is_directory: bool = False
7733 *
7734 dir_fd: dir_fd(requires='symlinkat')=None
7735
7736# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7737
7738Create a symbolic link pointing to src named dst.
7739
7740target_is_directory is required on Windows if the target is to be
7741 interpreted as a directory. (On Windows, symlink requires
7742 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7743 target_is_directory is ignored on non-Windows platforms.
7744
7745If dir_fd is not None, it should be a file descriptor open to a directory,
7746 and path should be relative; path will then be relative to that directory.
7747dir_fd may not be implemented on your platform.
7748 If it is unavailable, using it will raise a NotImplementedError.
7749
7750[clinic start generated code]*/
7751
Larry Hastings2f936352014-08-05 14:04:04 +10007752static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007753os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007754 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007755/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007756{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007757#ifdef MS_WINDOWS
7758 DWORD result;
7759#else
7760 int result;
7761#endif
7762
Larry Hastings9cf065c2012-06-22 16:30:09 -07007763#ifdef MS_WINDOWS
7764 if (!check_CreateSymbolicLink()) {
7765 PyErr_SetString(PyExc_NotImplementedError,
7766 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007767 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007768 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007769 if (!win32_can_symlink) {
7770 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007771 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007772 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007773#endif
7774
Larry Hastings9cf065c2012-06-22 16:30:09 -07007775#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007776
Larry Hastings9cf065c2012-06-22 16:30:09 -07007777 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007778 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007779 /* if src is a directory, ensure target_is_directory==1 */
7780 target_is_directory |= _check_dirW(src->wide, dst->wide);
7781 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7782 target_is_directory);
Steve Dower6921e732018-03-05 14:26:08 -08007783 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007784 Py_END_ALLOW_THREADS
7785
Larry Hastings2f936352014-08-05 14:04:04 +10007786 if (!result)
7787 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007788
7789#else
7790
Steve Dower6921e732018-03-05 14:26:08 -08007791 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7792 PyErr_SetString(PyExc_ValueError,
7793 "symlink: src and dst must be the same type");
7794 return NULL;
7795 }
7796
Larry Hastings9cf065c2012-06-22 16:30:09 -07007797 Py_BEGIN_ALLOW_THREADS
7798#if HAVE_SYMLINKAT
7799 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007800 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007801 else
7802#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007803 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007804 Py_END_ALLOW_THREADS
7805
Larry Hastings2f936352014-08-05 14:04:04 +10007806 if (result)
7807 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007808#endif
7809
Larry Hastings2f936352014-08-05 14:04:04 +10007810 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007811}
7812#endif /* HAVE_SYMLINK */
7813
Larry Hastings9cf065c2012-06-22 16:30:09 -07007814
Brian Curtind40e6f72010-07-08 21:39:08 +00007815
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007816
Larry Hastings605a62d2012-06-24 04:33:36 -07007817static PyStructSequence_Field times_result_fields[] = {
7818 {"user", "user time"},
7819 {"system", "system time"},
7820 {"children_user", "user time of children"},
7821 {"children_system", "system time of children"},
7822 {"elapsed", "elapsed time since an arbitrary point in the past"},
7823 {NULL}
7824};
7825
7826PyDoc_STRVAR(times_result__doc__,
7827"times_result: Result from os.times().\n\n\
7828This object may be accessed either as a tuple of\n\
7829 (user, system, children_user, children_system, elapsed),\n\
7830or via the attributes user, system, children_user, children_system,\n\
7831and elapsed.\n\
7832\n\
7833See os.times for more information.");
7834
7835static PyStructSequence_Desc times_result_desc = {
7836 "times_result", /* name */
7837 times_result__doc__, /* doc */
7838 times_result_fields,
7839 5
7840};
7841
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007842static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07007843
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007844#ifdef MS_WINDOWS
7845#define HAVE_TIMES /* mandatory, for the method table */
7846#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007847
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007848#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007849
7850static PyObject *
7851build_times_result(double user, double system,
7852 double children_user, double children_system,
7853 double elapsed)
7854{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007855 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07007856 if (value == NULL)
7857 return NULL;
7858
7859#define SET(i, field) \
7860 { \
7861 PyObject *o = PyFloat_FromDouble(field); \
7862 if (!o) { \
7863 Py_DECREF(value); \
7864 return NULL; \
7865 } \
7866 PyStructSequence_SET_ITEM(value, i, o); \
7867 } \
7868
7869 SET(0, user);
7870 SET(1, system);
7871 SET(2, children_user);
7872 SET(3, children_system);
7873 SET(4, elapsed);
7874
7875#undef SET
7876
7877 return value;
7878}
7879
Larry Hastings605a62d2012-06-24 04:33:36 -07007880
Larry Hastings2f936352014-08-05 14:04:04 +10007881#ifndef MS_WINDOWS
7882#define NEED_TICKS_PER_SECOND
7883static long ticks_per_second = -1;
7884#endif /* MS_WINDOWS */
7885
7886/*[clinic input]
7887os.times
7888
7889Return a collection containing process timing information.
7890
7891The object returned behaves like a named tuple with these fields:
7892 (utime, stime, cutime, cstime, elapsed_time)
7893All fields are floating point numbers.
7894[clinic start generated code]*/
7895
Larry Hastings2f936352014-08-05 14:04:04 +10007896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007897os_times_impl(PyObject *module)
7898/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007899#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007900{
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 FILETIME create, exit, kernel, user;
7902 HANDLE hProc;
7903 hProc = GetCurrentProcess();
7904 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7905 /* The fields of a FILETIME structure are the hi and lo part
7906 of a 64-bit value expressed in 100 nanosecond units.
7907 1e7 is one second in such units; 1e-7 the inverse.
7908 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7909 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007910 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007911 (double)(user.dwHighDateTime*429.4967296 +
7912 user.dwLowDateTime*1e-7),
7913 (double)(kernel.dwHighDateTime*429.4967296 +
7914 kernel.dwLowDateTime*1e-7),
7915 (double)0,
7916 (double)0,
7917 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007918}
Larry Hastings2f936352014-08-05 14:04:04 +10007919#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007920{
Larry Hastings2f936352014-08-05 14:04:04 +10007921
7922
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007923 struct tms t;
7924 clock_t c;
7925 errno = 0;
7926 c = times(&t);
7927 if (c == (clock_t) -1)
7928 return posix_error();
7929 return build_times_result(
7930 (double)t.tms_utime / ticks_per_second,
7931 (double)t.tms_stime / ticks_per_second,
7932 (double)t.tms_cutime / ticks_per_second,
7933 (double)t.tms_cstime / ticks_per_second,
7934 (double)c / ticks_per_second);
7935}
Larry Hastings2f936352014-08-05 14:04:04 +10007936#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007937#endif /* HAVE_TIMES */
7938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007939
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007940#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007941/*[clinic input]
7942os.getsid
7943
7944 pid: pid_t
7945 /
7946
7947Call the system call getsid(pid) and return the result.
7948[clinic start generated code]*/
7949
Larry Hastings2f936352014-08-05 14:04:04 +10007950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007951os_getsid_impl(PyObject *module, pid_t pid)
7952/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007953{
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 sid = getsid(pid);
7956 if (sid < 0)
7957 return posix_error();
7958 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007959}
7960#endif /* HAVE_GETSID */
7961
7962
Guido van Rossumb6775db1994-08-01 11:34:53 +00007963#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007964/*[clinic input]
7965os.setsid
7966
7967Call the system call setsid().
7968[clinic start generated code]*/
7969
Larry Hastings2f936352014-08-05 14:04:04 +10007970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007971os_setsid_impl(PyObject *module)
7972/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007973{
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 if (setsid() < 0)
7975 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007976 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007977}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007978#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007979
Larry Hastings2f936352014-08-05 14:04:04 +10007980
Guido van Rossumb6775db1994-08-01 11:34:53 +00007981#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007982/*[clinic input]
7983os.setpgid
7984
7985 pid: pid_t
7986 pgrp: pid_t
7987 /
7988
7989Call the system call setpgid(pid, pgrp).
7990[clinic start generated code]*/
7991
Larry Hastings2f936352014-08-05 14:04:04 +10007992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007993os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7994/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007995{
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 if (setpgid(pid, pgrp) < 0)
7997 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007998 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007999}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008000#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008002
Guido van Rossumb6775db1994-08-01 11:34:53 +00008003#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008004/*[clinic input]
8005os.tcgetpgrp
8006
8007 fd: int
8008 /
8009
8010Return the process group associated with the terminal specified by fd.
8011[clinic start generated code]*/
8012
Larry Hastings2f936352014-08-05 14:04:04 +10008013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008014os_tcgetpgrp_impl(PyObject *module, int fd)
8015/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008016{
8017 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 if (pgid < 0)
8019 return posix_error();
8020 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008021}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008022#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008024
Guido van Rossumb6775db1994-08-01 11:34:53 +00008025#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008026/*[clinic input]
8027os.tcsetpgrp
8028
8029 fd: int
8030 pgid: pid_t
8031 /
8032
8033Set the process group associated with the terminal specified by fd.
8034[clinic start generated code]*/
8035
Larry Hastings2f936352014-08-05 14:04:04 +10008036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008037os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8038/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008039{
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 if (tcsetpgrp(fd, pgid) < 0)
8041 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008042 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008043}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008044#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008045
Guido van Rossum687dd131993-05-17 08:34:16 +00008046/* Functions acting on file descriptors */
8047
Victor Stinnerdaf45552013-08-28 00:53:59 +02008048#ifdef O_CLOEXEC
8049extern int _Py_open_cloexec_works;
8050#endif
8051
Larry Hastings2f936352014-08-05 14:04:04 +10008052
8053/*[clinic input]
8054os.open -> int
8055 path: path_t
8056 flags: int
8057 mode: int = 0o777
8058 *
8059 dir_fd: dir_fd(requires='openat') = None
8060
8061# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8062
8063Open a file for low level IO. Returns a file descriptor (integer).
8064
8065If dir_fd is not None, it should be a file descriptor open to a directory,
8066 and path should be relative; path will then be relative to that directory.
8067dir_fd may not be implemented on your platform.
8068 If it is unavailable, using it will raise a NotImplementedError.
8069[clinic start generated code]*/
8070
Larry Hastings2f936352014-08-05 14:04:04 +10008071static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008072os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8073/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008074{
8075 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008076 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008077
Victor Stinnerdaf45552013-08-28 00:53:59 +02008078#ifdef O_CLOEXEC
8079 int *atomic_flag_works = &_Py_open_cloexec_works;
8080#elif !defined(MS_WINDOWS)
8081 int *atomic_flag_works = NULL;
8082#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008083
Victor Stinnerdaf45552013-08-28 00:53:59 +02008084#ifdef MS_WINDOWS
8085 flags |= O_NOINHERIT;
8086#elif defined(O_CLOEXEC)
8087 flags |= O_CLOEXEC;
8088#endif
8089
Steve Dower8fc89802015-04-12 00:26:27 -04008090 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008091 do {
8092 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008093#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008094 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008095#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008096#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008097 if (dir_fd != DEFAULT_DIR_FD)
8098 fd = openat(dir_fd, path->narrow, flags, mode);
8099 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008100#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008101 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008102#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008103 Py_END_ALLOW_THREADS
8104 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008105 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008106
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008107 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008108 if (!async_err)
8109 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008110 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008111 }
8112
Victor Stinnerdaf45552013-08-28 00:53:59 +02008113#ifndef MS_WINDOWS
8114 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8115 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008116 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008117 }
8118#endif
8119
Larry Hastings2f936352014-08-05 14:04:04 +10008120 return fd;
8121}
8122
8123
8124/*[clinic input]
8125os.close
8126
8127 fd: int
8128
8129Close a file descriptor.
8130[clinic start generated code]*/
8131
Barry Warsaw53699e91996-12-10 23:23:01 +00008132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008133os_close_impl(PyObject *module, int fd)
8134/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008135{
Larry Hastings2f936352014-08-05 14:04:04 +10008136 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008137 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8138 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8139 * for more details.
8140 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008142 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008144 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 Py_END_ALLOW_THREADS
8146 if (res < 0)
8147 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008148 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008149}
8150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008151
Larry Hastings2f936352014-08-05 14:04:04 +10008152/*[clinic input]
8153os.closerange
8154
8155 fd_low: int
8156 fd_high: int
8157 /
8158
8159Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8160[clinic start generated code]*/
8161
Larry Hastings2f936352014-08-05 14:04:04 +10008162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008163os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8164/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008165{
8166 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008168 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008169 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008170 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008171 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 Py_END_ALLOW_THREADS
8173 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008174}
8175
8176
Larry Hastings2f936352014-08-05 14:04:04 +10008177/*[clinic input]
8178os.dup -> int
8179
8180 fd: int
8181 /
8182
8183Return a duplicate of a file descriptor.
8184[clinic start generated code]*/
8185
Larry Hastings2f936352014-08-05 14:04:04 +10008186static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008187os_dup_impl(PyObject *module, int fd)
8188/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008189{
8190 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008191}
8192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008193
Larry Hastings2f936352014-08-05 14:04:04 +10008194/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008195os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008196 fd: int
8197 fd2: int
8198 inheritable: bool=True
8199
8200Duplicate file descriptor.
8201[clinic start generated code]*/
8202
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008203static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008204os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008205/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008206{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008207 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008208#if defined(HAVE_DUP3) && \
8209 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8210 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008211 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008212#endif
8213
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008214 if (fd < 0 || fd2 < 0) {
8215 posix_error();
8216 return -1;
8217 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008218
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008219 /* dup2() can fail with EINTR if the target FD is already open, because it
8220 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8221 * upon close(), and therefore below.
8222 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008223#ifdef MS_WINDOWS
8224 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008225 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008226 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008227 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008228 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008229 if (res < 0) {
8230 posix_error();
8231 return -1;
8232 }
8233 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008234
8235 /* Character files like console cannot be make non-inheritable */
8236 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8237 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008238 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008239 }
8240
8241#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8242 Py_BEGIN_ALLOW_THREADS
8243 if (!inheritable)
8244 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8245 else
8246 res = dup2(fd, fd2);
8247 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008248 if (res < 0) {
8249 posix_error();
8250 return -1;
8251 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008252
8253#else
8254
8255#ifdef HAVE_DUP3
8256 if (!inheritable && dup3_works != 0) {
8257 Py_BEGIN_ALLOW_THREADS
8258 res = dup3(fd, fd2, O_CLOEXEC);
8259 Py_END_ALLOW_THREADS
8260 if (res < 0) {
8261 if (dup3_works == -1)
8262 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008263 if (dup3_works) {
8264 posix_error();
8265 return -1;
8266 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008267 }
8268 }
8269
8270 if (inheritable || dup3_works == 0)
8271 {
8272#endif
8273 Py_BEGIN_ALLOW_THREADS
8274 res = dup2(fd, fd2);
8275 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008276 if (res < 0) {
8277 posix_error();
8278 return -1;
8279 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008280
8281 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8282 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008283 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008284 }
8285#ifdef HAVE_DUP3
8286 }
8287#endif
8288
8289#endif
8290
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008291 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008292}
8293
Larry Hastings2f936352014-08-05 14:04:04 +10008294
Ross Lagerwall7807c352011-03-17 20:20:30 +02008295#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008296/*[clinic input]
8297os.lockf
8298
8299 fd: int
8300 An open file descriptor.
8301 command: int
8302 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8303 length: Py_off_t
8304 The number of bytes to lock, starting at the current position.
8305 /
8306
8307Apply, test or remove a POSIX lock on an open file descriptor.
8308
8309[clinic start generated code]*/
8310
Larry Hastings2f936352014-08-05 14:04:04 +10008311static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008312os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8313/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008314{
8315 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008316
8317 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008318 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008319 Py_END_ALLOW_THREADS
8320
8321 if (res < 0)
8322 return posix_error();
8323
8324 Py_RETURN_NONE;
8325}
Larry Hastings2f936352014-08-05 14:04:04 +10008326#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008328
Larry Hastings2f936352014-08-05 14:04:04 +10008329/*[clinic input]
8330os.lseek -> Py_off_t
8331
8332 fd: int
8333 position: Py_off_t
8334 how: int
8335 /
8336
8337Set the position of a file descriptor. Return the new position.
8338
8339Return the new cursor position in number of bytes
8340relative to the beginning of the file.
8341[clinic start generated code]*/
8342
Larry Hastings2f936352014-08-05 14:04:04 +10008343static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008344os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8345/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008346{
8347 Py_off_t result;
8348
Guido van Rossum687dd131993-05-17 08:34:16 +00008349#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008350 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8351 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008352 case 0: how = SEEK_SET; break;
8353 case 1: how = SEEK_CUR; break;
8354 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008355 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008356#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008357
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008359 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008360#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008361 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008362#else
Larry Hastings2f936352014-08-05 14:04:04 +10008363 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008364#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008365 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008367 if (result < 0)
8368 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008369
Larry Hastings2f936352014-08-05 14:04:04 +10008370 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008371}
8372
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008373
Larry Hastings2f936352014-08-05 14:04:04 +10008374/*[clinic input]
8375os.read
8376 fd: int
8377 length: Py_ssize_t
8378 /
8379
8380Read from a file descriptor. Returns a bytes object.
8381[clinic start generated code]*/
8382
Larry Hastings2f936352014-08-05 14:04:04 +10008383static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008384os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8385/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008386{
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 Py_ssize_t n;
8388 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008389
8390 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008391 errno = EINVAL;
8392 return posix_error();
8393 }
Larry Hastings2f936352014-08-05 14:04:04 +10008394
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008395 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008396
8397 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008398 if (buffer == NULL)
8399 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008400
Victor Stinner66aab0c2015-03-19 22:53:20 +01008401 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8402 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008404 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 }
Larry Hastings2f936352014-08-05 14:04:04 +10008406
8407 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008408 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008409
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008411}
8412
Ross Lagerwall7807c352011-03-17 20:20:30 +02008413#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008414 || defined(__APPLE__))) \
8415 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8416 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8417static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008418iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008419{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008420 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008421
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008422 *iov = PyMem_New(struct iovec, cnt);
8423 if (*iov == NULL) {
8424 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008425 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008426 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008427
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008428 *buf = PyMem_New(Py_buffer, cnt);
8429 if (*buf == NULL) {
8430 PyMem_Del(*iov);
8431 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008432 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008433 }
8434
8435 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008436 PyObject *item = PySequence_GetItem(seq, i);
8437 if (item == NULL)
8438 goto fail;
8439 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8440 Py_DECREF(item);
8441 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008442 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008443 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008444 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008445 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008446 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008447 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008448
8449fail:
8450 PyMem_Del(*iov);
8451 for (j = 0; j < i; j++) {
8452 PyBuffer_Release(&(*buf)[j]);
8453 }
8454 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008455 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008456}
8457
8458static void
8459iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8460{
8461 int i;
8462 PyMem_Del(iov);
8463 for (i = 0; i < cnt; i++) {
8464 PyBuffer_Release(&buf[i]);
8465 }
8466 PyMem_Del(buf);
8467}
8468#endif
8469
Larry Hastings2f936352014-08-05 14:04:04 +10008470
Ross Lagerwall7807c352011-03-17 20:20:30 +02008471#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008472/*[clinic input]
8473os.readv -> Py_ssize_t
8474
8475 fd: int
8476 buffers: object
8477 /
8478
8479Read from a file descriptor fd into an iterable of buffers.
8480
8481The buffers should be mutable buffers accepting bytes.
8482readv will transfer data into each buffer until it is full
8483and then move on to the next buffer in the sequence to hold
8484the rest of the data.
8485
8486readv returns the total number of bytes read,
8487which may be less than the total capacity of all the buffers.
8488[clinic start generated code]*/
8489
Larry Hastings2f936352014-08-05 14:04:04 +10008490static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008491os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8492/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008493{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008494 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008495 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008496 struct iovec *iov;
8497 Py_buffer *buf;
8498
Larry Hastings2f936352014-08-05 14:04:04 +10008499 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008500 PyErr_SetString(PyExc_TypeError,
8501 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008502 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008503 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008504
Larry Hastings2f936352014-08-05 14:04:04 +10008505 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008506 if (cnt < 0)
8507 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008508
8509 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8510 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008511
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008512 do {
8513 Py_BEGIN_ALLOW_THREADS
8514 n = readv(fd, iov, cnt);
8515 Py_END_ALLOW_THREADS
8516 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008517
8518 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008519 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008520 if (!async_err)
8521 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008522 return -1;
8523 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008524
Larry Hastings2f936352014-08-05 14:04:04 +10008525 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008526}
Larry Hastings2f936352014-08-05 14:04:04 +10008527#endif /* HAVE_READV */
8528
Ross Lagerwall7807c352011-03-17 20:20:30 +02008529
8530#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008531/*[clinic input]
8532# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8533os.pread
8534
8535 fd: int
8536 length: int
8537 offset: Py_off_t
8538 /
8539
8540Read a number of bytes from a file descriptor starting at a particular offset.
8541
8542Read length bytes from file descriptor fd, starting at offset bytes from
8543the beginning of the file. The file offset remains unchanged.
8544[clinic start generated code]*/
8545
Larry Hastings2f936352014-08-05 14:04:04 +10008546static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008547os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8548/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008549{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008550 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008551 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008552 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008553
Larry Hastings2f936352014-08-05 14:04:04 +10008554 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008555 errno = EINVAL;
8556 return posix_error();
8557 }
Larry Hastings2f936352014-08-05 14:04:04 +10008558 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008559 if (buffer == NULL)
8560 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008561
8562 do {
8563 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008564 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008565 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008566 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008567 Py_END_ALLOW_THREADS
8568 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8569
Ross Lagerwall7807c352011-03-17 20:20:30 +02008570 if (n < 0) {
8571 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008572 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008573 }
Larry Hastings2f936352014-08-05 14:04:04 +10008574 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008575 _PyBytes_Resize(&buffer, n);
8576 return buffer;
8577}
Larry Hastings2f936352014-08-05 14:04:04 +10008578#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008579
Pablo Galindo4defba32018-01-27 16:16:37 +00008580#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8581/*[clinic input]
8582os.preadv -> Py_ssize_t
8583
8584 fd: int
8585 buffers: object
8586 offset: Py_off_t
8587 flags: int = 0
8588 /
8589
8590Reads from a file descriptor into a number of mutable bytes-like objects.
8591
8592Combines the functionality of readv() and pread(). As readv(), it will
8593transfer data into each buffer until it is full and then move on to the next
8594buffer in the sequence to hold the rest of the data. Its fourth argument,
8595specifies the file offset at which the input operation is to be performed. It
8596will return the total number of bytes read (which can be less than the total
8597capacity of all the objects).
8598
8599The flags argument contains a bitwise OR of zero or more of the following flags:
8600
8601- RWF_HIPRI
8602- RWF_NOWAIT
8603
8604Using non-zero flags requires Linux 4.6 or newer.
8605[clinic start generated code]*/
8606
8607static Py_ssize_t
8608os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8609 int flags)
8610/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8611{
8612 Py_ssize_t cnt, n;
8613 int async_err = 0;
8614 struct iovec *iov;
8615 Py_buffer *buf;
8616
8617 if (!PySequence_Check(buffers)) {
8618 PyErr_SetString(PyExc_TypeError,
8619 "preadv2() arg 2 must be a sequence");
8620 return -1;
8621 }
8622
8623 cnt = PySequence_Size(buffers);
8624 if (cnt < 0) {
8625 return -1;
8626 }
8627
8628#ifndef HAVE_PREADV2
8629 if(flags != 0) {
8630 argument_unavailable_error("preadv2", "flags");
8631 return -1;
8632 }
8633#endif
8634
8635 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8636 return -1;
8637 }
8638#ifdef HAVE_PREADV2
8639 do {
8640 Py_BEGIN_ALLOW_THREADS
8641 _Py_BEGIN_SUPPRESS_IPH
8642 n = preadv2(fd, iov, cnt, offset, flags);
8643 _Py_END_SUPPRESS_IPH
8644 Py_END_ALLOW_THREADS
8645 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8646#else
8647 do {
8648 Py_BEGIN_ALLOW_THREADS
8649 _Py_BEGIN_SUPPRESS_IPH
8650 n = preadv(fd, iov, cnt, offset);
8651 _Py_END_SUPPRESS_IPH
8652 Py_END_ALLOW_THREADS
8653 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8654#endif
8655
8656 iov_cleanup(iov, buf, cnt);
8657 if (n < 0) {
8658 if (!async_err) {
8659 posix_error();
8660 }
8661 return -1;
8662 }
8663
8664 return n;
8665}
8666#endif /* HAVE_PREADV */
8667
Larry Hastings2f936352014-08-05 14:04:04 +10008668
8669/*[clinic input]
8670os.write -> Py_ssize_t
8671
8672 fd: int
8673 data: Py_buffer
8674 /
8675
8676Write a bytes object to a file descriptor.
8677[clinic start generated code]*/
8678
Larry Hastings2f936352014-08-05 14:04:04 +10008679static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008680os_write_impl(PyObject *module, int fd, Py_buffer *data)
8681/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008682{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008683 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008684}
8685
8686#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008687PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008688"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008689sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008690 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008691Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008692
Larry Hastings2f936352014-08-05 14:04:04 +10008693/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008694static PyObject *
8695posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8696{
8697 int in, out;
8698 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008699 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008700 off_t offset;
8701
8702#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8703#ifndef __APPLE__
8704 Py_ssize_t len;
8705#endif
8706 PyObject *headers = NULL, *trailers = NULL;
8707 Py_buffer *hbuf, *tbuf;
8708 off_t sbytes;
8709 struct sf_hdtr sf;
8710 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008711 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008712 static char *keywords[] = {"out", "in",
8713 "offset", "count",
8714 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008715
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008716 sf.headers = NULL;
8717 sf.trailers = NULL;
8718
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008719#ifdef __APPLE__
8720 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008721 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008722#else
8723 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008724 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008725#endif
8726 &headers, &trailers, &flags))
8727 return NULL;
8728 if (headers != NULL) {
8729 if (!PySequence_Check(headers)) {
8730 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008731 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008732 return NULL;
8733 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008734 Py_ssize_t i = PySequence_Size(headers);
8735 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008736 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008737 if (i > INT_MAX) {
8738 PyErr_SetString(PyExc_OverflowError,
8739 "sendfile() header is too large");
8740 return NULL;
8741 }
8742 if (i > 0) {
8743 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008744 if (iov_setup(&(sf.headers), &hbuf,
8745 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008746 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008747#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008748 for (i = 0; i < sf.hdr_cnt; i++) {
8749 Py_ssize_t blen = sf.headers[i].iov_len;
8750# define OFF_T_MAX 0x7fffffffffffffff
8751 if (sbytes >= OFF_T_MAX - blen) {
8752 PyErr_SetString(PyExc_OverflowError,
8753 "sendfile() header is too large");
8754 return NULL;
8755 }
8756 sbytes += blen;
8757 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008758#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008759 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008760 }
8761 }
8762 if (trailers != NULL) {
8763 if (!PySequence_Check(trailers)) {
8764 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008765 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008766 return NULL;
8767 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008768 Py_ssize_t i = PySequence_Size(trailers);
8769 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008770 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008771 if (i > INT_MAX) {
8772 PyErr_SetString(PyExc_OverflowError,
8773 "sendfile() trailer is too large");
8774 return NULL;
8775 }
8776 if (i > 0) {
8777 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008778 if (iov_setup(&(sf.trailers), &tbuf,
8779 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008780 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008781 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008782 }
8783 }
8784
Steve Dower8fc89802015-04-12 00:26:27 -04008785 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008786 do {
8787 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008788#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008789 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008790#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008791 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008792#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008793 Py_END_ALLOW_THREADS
8794 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008795 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008796
8797 if (sf.headers != NULL)
8798 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8799 if (sf.trailers != NULL)
8800 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8801
8802 if (ret < 0) {
8803 if ((errno == EAGAIN) || (errno == EBUSY)) {
8804 if (sbytes != 0) {
8805 // some data has been sent
8806 goto done;
8807 }
8808 else {
8809 // no data has been sent; upper application is supposed
8810 // to retry on EAGAIN or EBUSY
8811 return posix_error();
8812 }
8813 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008814 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008815 }
8816 goto done;
8817
8818done:
8819 #if !defined(HAVE_LARGEFILE_SUPPORT)
8820 return Py_BuildValue("l", sbytes);
8821 #else
8822 return Py_BuildValue("L", sbytes);
8823 #endif
8824
8825#else
8826 Py_ssize_t count;
8827 PyObject *offobj;
8828 static char *keywords[] = {"out", "in",
8829 "offset", "count", NULL};
8830 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8831 keywords, &out, &in, &offobj, &count))
8832 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008833#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008834 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008835 do {
8836 Py_BEGIN_ALLOW_THREADS
8837 ret = sendfile(out, in, NULL, count);
8838 Py_END_ALLOW_THREADS
8839 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008840 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008841 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008842 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008843 }
8844#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008845 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008846 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008847
8848 do {
8849 Py_BEGIN_ALLOW_THREADS
8850 ret = sendfile(out, in, &offset, count);
8851 Py_END_ALLOW_THREADS
8852 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008853 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008854 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008855 return Py_BuildValue("n", ret);
8856#endif
8857}
Larry Hastings2f936352014-08-05 14:04:04 +10008858#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008859
Larry Hastings2f936352014-08-05 14:04:04 +10008860
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008861#if defined(__APPLE__)
8862/*[clinic input]
8863os._fcopyfile
8864
8865 infd: int
8866 outfd: int
8867 flags: int
8868 /
8869
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008870Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008871[clinic start generated code]*/
8872
8873static PyObject *
8874os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008875/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008876{
8877 int ret;
8878
8879 Py_BEGIN_ALLOW_THREADS
8880 ret = fcopyfile(infd, outfd, NULL, flags);
8881 Py_END_ALLOW_THREADS
8882 if (ret < 0)
8883 return posix_error();
8884 Py_RETURN_NONE;
8885}
8886#endif
8887
8888
Larry Hastings2f936352014-08-05 14:04:04 +10008889/*[clinic input]
8890os.fstat
8891
8892 fd : int
8893
8894Perform a stat system call on the given file descriptor.
8895
8896Like stat(), but for an open file descriptor.
8897Equivalent to os.stat(fd).
8898[clinic start generated code]*/
8899
Larry Hastings2f936352014-08-05 14:04:04 +10008900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008901os_fstat_impl(PyObject *module, int fd)
8902/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008903{
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 STRUCT_STAT st;
8905 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008906 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008907
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008908 do {
8909 Py_BEGIN_ALLOW_THREADS
8910 res = FSTAT(fd, &st);
8911 Py_END_ALLOW_THREADS
8912 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008914#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008915 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008916#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008917 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008918#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 }
Tim Peters5aa91602002-01-30 05:46:57 +00008920
Victor Stinner4195b5c2012-02-08 23:03:19 +01008921 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008922}
8923
Larry Hastings2f936352014-08-05 14:04:04 +10008924
8925/*[clinic input]
8926os.isatty -> bool
8927 fd: int
8928 /
8929
8930Return True if the fd is connected to a terminal.
8931
8932Return True if the file descriptor is an open file descriptor
8933connected to the slave end of a terminal.
8934[clinic start generated code]*/
8935
Larry Hastings2f936352014-08-05 14:04:04 +10008936static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008937os_isatty_impl(PyObject *module, int fd)
8938/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008939{
Steve Dower8fc89802015-04-12 00:26:27 -04008940 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008941 _Py_BEGIN_SUPPRESS_IPH
8942 return_value = isatty(fd);
8943 _Py_END_SUPPRESS_IPH
8944 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008945}
8946
8947
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008948#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008949/*[clinic input]
8950os.pipe
8951
8952Create a pipe.
8953
8954Returns a tuple of two file descriptors:
8955 (read_fd, write_fd)
8956[clinic start generated code]*/
8957
Larry Hastings2f936352014-08-05 14:04:04 +10008958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008959os_pipe_impl(PyObject *module)
8960/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008961{
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008963#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008965 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008967#else
8968 int res;
8969#endif
8970
8971#ifdef MS_WINDOWS
8972 attr.nLength = sizeof(attr);
8973 attr.lpSecurityDescriptor = NULL;
8974 attr.bInheritHandle = FALSE;
8975
8976 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008977 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008978 ok = CreatePipe(&read, &write, &attr, 0);
8979 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008980 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8981 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008982 if (fds[0] == -1 || fds[1] == -1) {
8983 CloseHandle(read);
8984 CloseHandle(write);
8985 ok = 0;
8986 }
8987 }
Steve Dowerc3630612016-11-19 18:41:16 -08008988 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008989 Py_END_ALLOW_THREADS
8990
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008992 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008993#else
8994
8995#ifdef HAVE_PIPE2
8996 Py_BEGIN_ALLOW_THREADS
8997 res = pipe2(fds, O_CLOEXEC);
8998 Py_END_ALLOW_THREADS
8999
9000 if (res != 0 && errno == ENOSYS)
9001 {
9002#endif
9003 Py_BEGIN_ALLOW_THREADS
9004 res = pipe(fds);
9005 Py_END_ALLOW_THREADS
9006
9007 if (res == 0) {
9008 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9009 close(fds[0]);
9010 close(fds[1]);
9011 return NULL;
9012 }
9013 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9014 close(fds[0]);
9015 close(fds[1]);
9016 return NULL;
9017 }
9018 }
9019#ifdef HAVE_PIPE2
9020 }
9021#endif
9022
9023 if (res != 0)
9024 return PyErr_SetFromErrno(PyExc_OSError);
9025#endif /* !MS_WINDOWS */
9026 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009027}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009028#endif /* HAVE_PIPE */
9029
Larry Hastings2f936352014-08-05 14:04:04 +10009030
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009031#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009032/*[clinic input]
9033os.pipe2
9034
9035 flags: int
9036 /
9037
9038Create a pipe with flags set atomically.
9039
9040Returns a tuple of two file descriptors:
9041 (read_fd, write_fd)
9042
9043flags can be constructed by ORing together one or more of these values:
9044O_NONBLOCK, O_CLOEXEC.
9045[clinic start generated code]*/
9046
Larry Hastings2f936352014-08-05 14:04:04 +10009047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009048os_pipe2_impl(PyObject *module, int flags)
9049/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009050{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009051 int fds[2];
9052 int res;
9053
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009054 res = pipe2(fds, flags);
9055 if (res != 0)
9056 return posix_error();
9057 return Py_BuildValue("(ii)", fds[0], fds[1]);
9058}
9059#endif /* HAVE_PIPE2 */
9060
Larry Hastings2f936352014-08-05 14:04:04 +10009061
Ross Lagerwall7807c352011-03-17 20:20:30 +02009062#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009063/*[clinic input]
9064os.writev -> Py_ssize_t
9065 fd: int
9066 buffers: object
9067 /
9068
9069Iterate over buffers, and write the contents of each to a file descriptor.
9070
9071Returns the total number of bytes written.
9072buffers must be a sequence of bytes-like objects.
9073[clinic start generated code]*/
9074
Larry Hastings2f936352014-08-05 14:04:04 +10009075static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009076os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9077/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009078{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009079 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009080 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009081 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009082 struct iovec *iov;
9083 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009084
9085 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009086 PyErr_SetString(PyExc_TypeError,
9087 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009088 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009089 }
Larry Hastings2f936352014-08-05 14:04:04 +10009090 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009091 if (cnt < 0)
9092 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009093
Larry Hastings2f936352014-08-05 14:04:04 +10009094 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9095 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009096 }
9097
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009098 do {
9099 Py_BEGIN_ALLOW_THREADS
9100 result = writev(fd, iov, cnt);
9101 Py_END_ALLOW_THREADS
9102 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009103
9104 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009105 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009106 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009107
Georg Brandl306336b2012-06-24 12:55:33 +02009108 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009109}
Larry Hastings2f936352014-08-05 14:04:04 +10009110#endif /* HAVE_WRITEV */
9111
9112
9113#ifdef HAVE_PWRITE
9114/*[clinic input]
9115os.pwrite -> Py_ssize_t
9116
9117 fd: int
9118 buffer: Py_buffer
9119 offset: Py_off_t
9120 /
9121
9122Write bytes to a file descriptor starting at a particular offset.
9123
9124Write buffer to fd, starting at offset bytes from the beginning of
9125the file. Returns the number of bytes writte. Does not change the
9126current file offset.
9127[clinic start generated code]*/
9128
Larry Hastings2f936352014-08-05 14:04:04 +10009129static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009130os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9131/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009132{
9133 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009134 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009135
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009136 do {
9137 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009138 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009139 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009140 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009141 Py_END_ALLOW_THREADS
9142 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009143
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009144 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009145 posix_error();
9146 return size;
9147}
9148#endif /* HAVE_PWRITE */
9149
Pablo Galindo4defba32018-01-27 16:16:37 +00009150#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9151/*[clinic input]
9152os.pwritev -> Py_ssize_t
9153
9154 fd: int
9155 buffers: object
9156 offset: Py_off_t
9157 flags: int = 0
9158 /
9159
9160Writes the contents of bytes-like objects to a file descriptor at a given offset.
9161
9162Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9163of bytes-like objects. Buffers are processed in array order. Entire contents of first
9164buffer is written before proceeding to second, and so on. The operating system may
9165set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9166This function writes the contents of each object to the file descriptor and returns
9167the total number of bytes written.
9168
9169The flags argument contains a bitwise OR of zero or more of the following flags:
9170
9171- RWF_DSYNC
9172- RWF_SYNC
9173
9174Using non-zero flags requires Linux 4.7 or newer.
9175[clinic start generated code]*/
9176
9177static Py_ssize_t
9178os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9179 int flags)
9180/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9181{
9182 Py_ssize_t cnt;
9183 Py_ssize_t result;
9184 int async_err = 0;
9185 struct iovec *iov;
9186 Py_buffer *buf;
9187
9188 if (!PySequence_Check(buffers)) {
9189 PyErr_SetString(PyExc_TypeError,
9190 "pwritev() arg 2 must be a sequence");
9191 return -1;
9192 }
9193
9194 cnt = PySequence_Size(buffers);
9195 if (cnt < 0) {
9196 return -1;
9197 }
9198
9199#ifndef HAVE_PWRITEV2
9200 if(flags != 0) {
9201 argument_unavailable_error("pwritev2", "flags");
9202 return -1;
9203 }
9204#endif
9205
9206 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9207 return -1;
9208 }
9209#ifdef HAVE_PWRITEV2
9210 do {
9211 Py_BEGIN_ALLOW_THREADS
9212 _Py_BEGIN_SUPPRESS_IPH
9213 result = pwritev2(fd, iov, cnt, offset, flags);
9214 _Py_END_SUPPRESS_IPH
9215 Py_END_ALLOW_THREADS
9216 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9217#else
9218 do {
9219 Py_BEGIN_ALLOW_THREADS
9220 _Py_BEGIN_SUPPRESS_IPH
9221 result = pwritev(fd, iov, cnt, offset);
9222 _Py_END_SUPPRESS_IPH
9223 Py_END_ALLOW_THREADS
9224 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9225#endif
9226
9227 iov_cleanup(iov, buf, cnt);
9228 if (result < 0) {
9229 if (!async_err) {
9230 posix_error();
9231 }
9232 return -1;
9233 }
9234
9235 return result;
9236}
9237#endif /* HAVE_PWRITEV */
9238
9239
9240
Larry Hastings2f936352014-08-05 14:04:04 +10009241
9242#ifdef HAVE_MKFIFO
9243/*[clinic input]
9244os.mkfifo
9245
9246 path: path_t
9247 mode: int=0o666
9248 *
9249 dir_fd: dir_fd(requires='mkfifoat')=None
9250
9251Create a "fifo" (a POSIX named pipe).
9252
9253If dir_fd is not None, it should be a file descriptor open to a directory,
9254 and path should be relative; path will then be relative to that directory.
9255dir_fd may not be implemented on your platform.
9256 If it is unavailable, using it will raise a NotImplementedError.
9257[clinic start generated code]*/
9258
Larry Hastings2f936352014-08-05 14:04:04 +10009259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009260os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9261/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009262{
9263 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009264 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009265
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009266 do {
9267 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009268#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009269 if (dir_fd != DEFAULT_DIR_FD)
9270 result = mkfifoat(dir_fd, path->narrow, mode);
9271 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009272#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009273 result = mkfifo(path->narrow, mode);
9274 Py_END_ALLOW_THREADS
9275 } while (result != 0 && errno == EINTR &&
9276 !(async_err = PyErr_CheckSignals()));
9277 if (result != 0)
9278 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009279
9280 Py_RETURN_NONE;
9281}
9282#endif /* HAVE_MKFIFO */
9283
9284
9285#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9286/*[clinic input]
9287os.mknod
9288
9289 path: path_t
9290 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009291 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009292 *
9293 dir_fd: dir_fd(requires='mknodat')=None
9294
9295Create a node in the file system.
9296
9297Create a node in the file system (file, device special file or named pipe)
9298at path. mode specifies both the permissions to use and the
9299type of node to be created, being combined (bitwise OR) with one of
9300S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9301device defines the newly created device special file (probably using
9302os.makedev()). Otherwise device is ignored.
9303
9304If dir_fd is not None, it should be a file descriptor open to a directory,
9305 and path should be relative; path will then be relative to that directory.
9306dir_fd may not be implemented on your platform.
9307 If it is unavailable, using it will raise a NotImplementedError.
9308[clinic start generated code]*/
9309
Larry Hastings2f936352014-08-05 14:04:04 +10009310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009311os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009312 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009313/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009314{
9315 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009316 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009317
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009318 do {
9319 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009320#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009321 if (dir_fd != DEFAULT_DIR_FD)
9322 result = mknodat(dir_fd, path->narrow, mode, device);
9323 else
Larry Hastings2f936352014-08-05 14:04:04 +10009324#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009325 result = mknod(path->narrow, mode, device);
9326 Py_END_ALLOW_THREADS
9327 } while (result != 0 && errno == EINTR &&
9328 !(async_err = PyErr_CheckSignals()));
9329 if (result != 0)
9330 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009331
9332 Py_RETURN_NONE;
9333}
9334#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9335
9336
9337#ifdef HAVE_DEVICE_MACROS
9338/*[clinic input]
9339os.major -> unsigned_int
9340
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009341 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009342 /
9343
9344Extracts a device major number from a raw device number.
9345[clinic start generated code]*/
9346
Larry Hastings2f936352014-08-05 14:04:04 +10009347static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009348os_major_impl(PyObject *module, dev_t device)
9349/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009350{
9351 return major(device);
9352}
9353
9354
9355/*[clinic input]
9356os.minor -> unsigned_int
9357
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009358 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009359 /
9360
9361Extracts a device minor number from a raw device number.
9362[clinic start generated code]*/
9363
Larry Hastings2f936352014-08-05 14:04:04 +10009364static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009365os_minor_impl(PyObject *module, dev_t device)
9366/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009367{
9368 return minor(device);
9369}
9370
9371
9372/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009373os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009374
9375 major: int
9376 minor: int
9377 /
9378
9379Composes a raw device number from the major and minor device numbers.
9380[clinic start generated code]*/
9381
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009382static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009383os_makedev_impl(PyObject *module, int major, int minor)
9384/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009385{
9386 return makedev(major, minor);
9387}
9388#endif /* HAVE_DEVICE_MACROS */
9389
9390
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009391#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009392/*[clinic input]
9393os.ftruncate
9394
9395 fd: int
9396 length: Py_off_t
9397 /
9398
9399Truncate a file, specified by file descriptor, to a specific length.
9400[clinic start generated code]*/
9401
Larry Hastings2f936352014-08-05 14:04:04 +10009402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009403os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9404/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009405{
9406 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009407 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009408
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009409 do {
9410 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009411 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009412#ifdef MS_WINDOWS
9413 result = _chsize_s(fd, length);
9414#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009415 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009416#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009417 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009418 Py_END_ALLOW_THREADS
9419 } while (result != 0 && errno == EINTR &&
9420 !(async_err = PyErr_CheckSignals()));
9421 if (result != 0)
9422 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009423 Py_RETURN_NONE;
9424}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009425#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009426
9427
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009428#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009429/*[clinic input]
9430os.truncate
9431 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9432 length: Py_off_t
9433
9434Truncate a file, specified by path, to a specific length.
9435
9436On some platforms, path may also be specified as an open file descriptor.
9437 If this functionality is unavailable, using it raises an exception.
9438[clinic start generated code]*/
9439
Larry Hastings2f936352014-08-05 14:04:04 +10009440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009441os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9442/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009443{
9444 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009445#ifdef MS_WINDOWS
9446 int fd;
9447#endif
9448
9449 if (path->fd != -1)
9450 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009451
9452 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009453 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009454#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009455 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009456 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009457 result = -1;
9458 else {
9459 result = _chsize_s(fd, length);
9460 close(fd);
9461 if (result < 0)
9462 errno = result;
9463 }
9464#else
9465 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009466#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009467 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009468 Py_END_ALLOW_THREADS
9469 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009470 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009471
9472 Py_RETURN_NONE;
9473}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009474#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009475
Ross Lagerwall7807c352011-03-17 20:20:30 +02009476
Victor Stinnerd6b17692014-09-30 12:20:05 +02009477/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9478 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9479 defined, which is the case in Python on AIX. AIX bug report:
9480 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9481#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9482# define POSIX_FADVISE_AIX_BUG
9483#endif
9484
Victor Stinnerec39e262014-09-30 12:35:58 +02009485
Victor Stinnerd6b17692014-09-30 12:20:05 +02009486#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009487/*[clinic input]
9488os.posix_fallocate
9489
9490 fd: int
9491 offset: Py_off_t
9492 length: Py_off_t
9493 /
9494
9495Ensure a file has allocated at least a particular number of bytes on disk.
9496
9497Ensure that the file specified by fd encompasses a range of bytes
9498starting at offset bytes from the beginning and continuing for length bytes.
9499[clinic start generated code]*/
9500
Larry Hastings2f936352014-08-05 14:04:04 +10009501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009502os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009503 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009504/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009505{
9506 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009507 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009508
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009509 do {
9510 Py_BEGIN_ALLOW_THREADS
9511 result = posix_fallocate(fd, offset, length);
9512 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009513 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9514
9515 if (result == 0)
9516 Py_RETURN_NONE;
9517
9518 if (async_err)
9519 return NULL;
9520
9521 errno = result;
9522 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009523}
Victor Stinnerec39e262014-09-30 12:35:58 +02009524#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009525
Ross Lagerwall7807c352011-03-17 20:20:30 +02009526
Victor Stinnerd6b17692014-09-30 12:20:05 +02009527#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009528/*[clinic input]
9529os.posix_fadvise
9530
9531 fd: int
9532 offset: Py_off_t
9533 length: Py_off_t
9534 advice: int
9535 /
9536
9537Announce an intention to access data in a specific pattern.
9538
9539Announce an intention to access data in a specific pattern, thus allowing
9540the kernel to make optimizations.
9541The advice applies to the region of the file specified by fd starting at
9542offset and continuing for length bytes.
9543advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9544POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9545POSIX_FADV_DONTNEED.
9546[clinic start generated code]*/
9547
Larry Hastings2f936352014-08-05 14:04:04 +10009548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009549os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009550 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009551/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009552{
9553 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009554 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009555
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009556 do {
9557 Py_BEGIN_ALLOW_THREADS
9558 result = posix_fadvise(fd, offset, length, advice);
9559 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009560 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9561
9562 if (result == 0)
9563 Py_RETURN_NONE;
9564
9565 if (async_err)
9566 return NULL;
9567
9568 errno = result;
9569 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009570}
Victor Stinnerec39e262014-09-30 12:35:58 +02009571#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009572
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009573#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009574
Fred Drake762e2061999-08-26 17:23:54 +00009575/* Save putenv() parameters as values here, so we can collect them when they
9576 * get re-set with another call for the same key. */
9577static PyObject *posix_putenv_garbage;
9578
Larry Hastings2f936352014-08-05 14:04:04 +10009579static void
9580posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009581{
Larry Hastings2f936352014-08-05 14:04:04 +10009582 /* Install the first arg and newstr in posix_putenv_garbage;
9583 * this will cause previous value to be collected. This has to
9584 * happen after the real putenv() call because the old value
9585 * was still accessible until then. */
9586 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9587 /* really not much we can do; just leak */
9588 PyErr_Clear();
9589 else
9590 Py_DECREF(value);
9591}
9592
9593
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009594#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009595/*[clinic input]
9596os.putenv
9597
9598 name: unicode
9599 value: unicode
9600 /
9601
9602Change or add an environment variable.
9603[clinic start generated code]*/
9604
Larry Hastings2f936352014-08-05 14:04:04 +10009605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009606os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9607/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009608{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009609 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009610 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009611
Serhiy Storchaka77703942017-06-25 07:33:01 +03009612 /* Search from index 1 because on Windows starting '=' is allowed for
9613 defining hidden environment variables. */
9614 if (PyUnicode_GET_LENGTH(name) == 0 ||
9615 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9616 {
9617 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9618 return NULL;
9619 }
Larry Hastings2f936352014-08-05 14:04:04 +10009620 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9621 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009622 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009623 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009624
9625 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9626 if (env == NULL)
9627 goto error;
9628 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009629 PyErr_Format(PyExc_ValueError,
9630 "the environment variable is longer than %u characters",
9631 _MAX_ENV);
9632 goto error;
9633 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009634 if (wcslen(env) != (size_t)size) {
9635 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009636 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009637 }
9638
Larry Hastings2f936352014-08-05 14:04:04 +10009639 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009641 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009643
Larry Hastings2f936352014-08-05 14:04:04 +10009644 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009645 Py_RETURN_NONE;
9646
9647error:
Larry Hastings2f936352014-08-05 14:04:04 +10009648 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009649 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009650}
Larry Hastings2f936352014-08-05 14:04:04 +10009651#else /* MS_WINDOWS */
9652/*[clinic input]
9653os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009654
Larry Hastings2f936352014-08-05 14:04:04 +10009655 name: FSConverter
9656 value: FSConverter
9657 /
9658
9659Change or add an environment variable.
9660[clinic start generated code]*/
9661
Larry Hastings2f936352014-08-05 14:04:04 +10009662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009663os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9664/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009665{
9666 PyObject *bytes = NULL;
9667 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009668 const char *name_string = PyBytes_AS_STRING(name);
9669 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009670
Serhiy Storchaka77703942017-06-25 07:33:01 +03009671 if (strchr(name_string, '=') != NULL) {
9672 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9673 return NULL;
9674 }
Larry Hastings2f936352014-08-05 14:04:04 +10009675 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9676 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009677 return NULL;
9678 }
9679
9680 env = PyBytes_AS_STRING(bytes);
9681 if (putenv(env)) {
9682 Py_DECREF(bytes);
9683 return posix_error();
9684 }
9685
9686 posix_putenv_garbage_setitem(name, bytes);
9687 Py_RETURN_NONE;
9688}
9689#endif /* MS_WINDOWS */
9690#endif /* HAVE_PUTENV */
9691
9692
9693#ifdef HAVE_UNSETENV
9694/*[clinic input]
9695os.unsetenv
9696 name: FSConverter
9697 /
9698
9699Delete an environment variable.
9700[clinic start generated code]*/
9701
Larry Hastings2f936352014-08-05 14:04:04 +10009702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009703os_unsetenv_impl(PyObject *module, PyObject *name)
9704/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009705{
Victor Stinner984890f2011-11-24 13:53:38 +01009706#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009707 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009708#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009709
Victor Stinner984890f2011-11-24 13:53:38 +01009710#ifdef HAVE_BROKEN_UNSETENV
9711 unsetenv(PyBytes_AS_STRING(name));
9712#else
Victor Stinner65170952011-11-22 22:16:17 +01009713 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009714 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009715 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009716#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009717
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 /* Remove the key from posix_putenv_garbage;
9719 * this will cause it to be collected. This has to
9720 * happen after the real unsetenv() call because the
9721 * old value was still accessible until then.
9722 */
Victor Stinner65170952011-11-22 22:16:17 +01009723 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 /* really not much we can do; just leak */
9725 PyErr_Clear();
9726 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009727 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009728}
Larry Hastings2f936352014-08-05 14:04:04 +10009729#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009730
Larry Hastings2f936352014-08-05 14:04:04 +10009731
9732/*[clinic input]
9733os.strerror
9734
9735 code: int
9736 /
9737
9738Translate an error code to a message string.
9739[clinic start generated code]*/
9740
Larry Hastings2f936352014-08-05 14:04:04 +10009741static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009742os_strerror_impl(PyObject *module, int code)
9743/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009744{
9745 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 if (message == NULL) {
9747 PyErr_SetString(PyExc_ValueError,
9748 "strerror() argument out of range");
9749 return NULL;
9750 }
Victor Stinner1b579672011-12-17 05:47:23 +01009751 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009752}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009753
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009754
Guido van Rossumc9641791998-08-04 15:26:23 +00009755#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009756#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009757/*[clinic input]
9758os.WCOREDUMP -> bool
9759
9760 status: int
9761 /
9762
9763Return True if the process returning status was dumped to a core file.
9764[clinic start generated code]*/
9765
Larry Hastings2f936352014-08-05 14:04:04 +10009766static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009767os_WCOREDUMP_impl(PyObject *module, int status)
9768/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009769{
9770 WAIT_TYPE wait_status;
9771 WAIT_STATUS_INT(wait_status) = status;
9772 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009773}
9774#endif /* WCOREDUMP */
9775
Larry Hastings2f936352014-08-05 14:04:04 +10009776
Fred Drake106c1a02002-04-23 15:58:02 +00009777#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009778/*[clinic input]
9779os.WIFCONTINUED -> bool
9780
9781 status: int
9782
9783Return True if a particular process was continued from a job control stop.
9784
9785Return True if the process returning status was continued from a
9786job control stop.
9787[clinic start generated code]*/
9788
Larry Hastings2f936352014-08-05 14:04:04 +10009789static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009790os_WIFCONTINUED_impl(PyObject *module, int status)
9791/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009792{
9793 WAIT_TYPE wait_status;
9794 WAIT_STATUS_INT(wait_status) = status;
9795 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009796}
9797#endif /* WIFCONTINUED */
9798
Larry Hastings2f936352014-08-05 14:04:04 +10009799
Guido van Rossumc9641791998-08-04 15:26:23 +00009800#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009801/*[clinic input]
9802os.WIFSTOPPED -> bool
9803
9804 status: int
9805
9806Return True if the process returning status was stopped.
9807[clinic start generated code]*/
9808
Larry Hastings2f936352014-08-05 14:04:04 +10009809static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009810os_WIFSTOPPED_impl(PyObject *module, int status)
9811/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009812{
9813 WAIT_TYPE wait_status;
9814 WAIT_STATUS_INT(wait_status) = status;
9815 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009816}
9817#endif /* WIFSTOPPED */
9818
Larry Hastings2f936352014-08-05 14:04:04 +10009819
Guido van Rossumc9641791998-08-04 15:26:23 +00009820#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009821/*[clinic input]
9822os.WIFSIGNALED -> bool
9823
9824 status: int
9825
9826Return True if the process returning status was terminated by a signal.
9827[clinic start generated code]*/
9828
Larry Hastings2f936352014-08-05 14:04:04 +10009829static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009830os_WIFSIGNALED_impl(PyObject *module, int status)
9831/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009832{
9833 WAIT_TYPE wait_status;
9834 WAIT_STATUS_INT(wait_status) = status;
9835 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009836}
9837#endif /* WIFSIGNALED */
9838
Larry Hastings2f936352014-08-05 14:04:04 +10009839
Guido van Rossumc9641791998-08-04 15:26:23 +00009840#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009841/*[clinic input]
9842os.WIFEXITED -> bool
9843
9844 status: int
9845
9846Return True if the process returning status exited via the exit() system call.
9847[clinic start generated code]*/
9848
Larry Hastings2f936352014-08-05 14:04:04 +10009849static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009850os_WIFEXITED_impl(PyObject *module, int status)
9851/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009852{
9853 WAIT_TYPE wait_status;
9854 WAIT_STATUS_INT(wait_status) = status;
9855 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009856}
9857#endif /* WIFEXITED */
9858
Larry Hastings2f936352014-08-05 14:04:04 +10009859
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009860#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009861/*[clinic input]
9862os.WEXITSTATUS -> int
9863
9864 status: int
9865
9866Return the process return code from status.
9867[clinic start generated code]*/
9868
Larry Hastings2f936352014-08-05 14:04:04 +10009869static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009870os_WEXITSTATUS_impl(PyObject *module, int status)
9871/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009872{
9873 WAIT_TYPE wait_status;
9874 WAIT_STATUS_INT(wait_status) = status;
9875 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009876}
9877#endif /* WEXITSTATUS */
9878
Larry Hastings2f936352014-08-05 14:04:04 +10009879
Guido van Rossumc9641791998-08-04 15:26:23 +00009880#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009881/*[clinic input]
9882os.WTERMSIG -> int
9883
9884 status: int
9885
9886Return the signal that terminated the process that provided the status value.
9887[clinic start generated code]*/
9888
Larry Hastings2f936352014-08-05 14:04:04 +10009889static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009890os_WTERMSIG_impl(PyObject *module, int status)
9891/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009892{
9893 WAIT_TYPE wait_status;
9894 WAIT_STATUS_INT(wait_status) = status;
9895 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009896}
9897#endif /* WTERMSIG */
9898
Larry Hastings2f936352014-08-05 14:04:04 +10009899
Guido van Rossumc9641791998-08-04 15:26:23 +00009900#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009901/*[clinic input]
9902os.WSTOPSIG -> int
9903
9904 status: int
9905
9906Return the signal that stopped the process that provided the status value.
9907[clinic start generated code]*/
9908
Larry Hastings2f936352014-08-05 14:04:04 +10009909static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009910os_WSTOPSIG_impl(PyObject *module, int status)
9911/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009912{
9913 WAIT_TYPE wait_status;
9914 WAIT_STATUS_INT(wait_status) = status;
9915 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009916}
9917#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009918#endif /* HAVE_SYS_WAIT_H */
9919
9920
Thomas Wouters477c8d52006-05-27 19:21:47 +00009921#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009922#ifdef _SCO_DS
9923/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9924 needed definitions in sys/statvfs.h */
9925#define _SVID3
9926#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009927#include <sys/statvfs.h>
9928
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009929static PyObject*
9930_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -08009931 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 if (v == NULL)
9933 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009934
9935#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9937 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9938 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9939 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9940 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9941 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9942 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9943 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9944 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9945 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009946#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9948 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9949 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009950 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009952 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009954 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009956 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009958 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009960 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9962 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009963#endif
Michael Felt502d5512018-01-05 13:01:58 +01009964/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9965 * (issue #32390). */
9966#if defined(_AIX) && defined(_ALL_SOURCE)
9967 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9968#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009969 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009970#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009971 if (PyErr_Occurred()) {
9972 Py_DECREF(v);
9973 return NULL;
9974 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009975
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009977}
9978
Larry Hastings2f936352014-08-05 14:04:04 +10009979
9980/*[clinic input]
9981os.fstatvfs
9982 fd: int
9983 /
9984
9985Perform an fstatvfs system call on the given fd.
9986
9987Equivalent to statvfs(fd).
9988[clinic start generated code]*/
9989
Larry Hastings2f936352014-08-05 14:04:04 +10009990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009991os_fstatvfs_impl(PyObject *module, int fd)
9992/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009993{
9994 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009995 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009997
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009998 do {
9999 Py_BEGIN_ALLOW_THREADS
10000 result = fstatvfs(fd, &st);
10001 Py_END_ALLOW_THREADS
10002 } while (result != 0 && errno == EINTR &&
10003 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010004 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010005 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010006
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010008}
Larry Hastings2f936352014-08-05 14:04:04 +100010009#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010010
10011
Thomas Wouters477c8d52006-05-27 19:21:47 +000010012#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010013#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010014/*[clinic input]
10015os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010016
Larry Hastings2f936352014-08-05 14:04:04 +100010017 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10018
10019Perform a statvfs system call on the given path.
10020
10021path may always be specified as a string.
10022On some platforms, path may also be specified as an open file descriptor.
10023 If this functionality is unavailable, using it raises an exception.
10024[clinic start generated code]*/
10025
Larry Hastings2f936352014-08-05 14:04:04 +100010026static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010027os_statvfs_impl(PyObject *module, path_t *path)
10028/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010029{
10030 int result;
10031 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010032
10033 Py_BEGIN_ALLOW_THREADS
10034#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010035 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010036#ifdef __APPLE__
10037 /* handle weak-linking on Mac OS X 10.3 */
10038 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010039 fd_specified("statvfs", path->fd);
10040 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010041 }
10042#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010043 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010044 }
10045 else
10046#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010047 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010048 Py_END_ALLOW_THREADS
10049
10050 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010051 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010052 }
10053
Larry Hastings2f936352014-08-05 14:04:04 +100010054 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010055}
Larry Hastings2f936352014-08-05 14:04:04 +100010056#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10057
Guido van Rossum94f6f721999-01-06 18:42:14 +000010058
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010059#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010060/*[clinic input]
10061os._getdiskusage
10062
Steve Dower23ad6d02018-02-22 10:39:10 -080010063 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010064
10065Return disk usage statistics about the given path as a (total, free) tuple.
10066[clinic start generated code]*/
10067
Larry Hastings2f936352014-08-05 14:04:04 +100010068static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010069os__getdiskusage_impl(PyObject *module, path_t *path)
10070/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010071{
10072 BOOL retval;
10073 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010074 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010075
10076 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010077 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010078 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010079 if (retval == 0) {
10080 if (GetLastError() == ERROR_DIRECTORY) {
10081 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010082
Joe Pamerc8c02492018-09-25 10:57:36 -040010083 dir_path = PyMem_New(wchar_t, path->length + 1);
10084 if (dir_path == NULL) {
10085 return PyErr_NoMemory();
10086 }
10087
10088 wcscpy_s(dir_path, path->length + 1, path->wide);
10089
10090 if (_dirnameW(dir_path) != -1) {
10091 Py_BEGIN_ALLOW_THREADS
10092 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10093 Py_END_ALLOW_THREADS
10094 }
10095 /* Record the last error in case it's modified by PyMem_Free. */
10096 err = GetLastError();
10097 PyMem_Free(dir_path);
10098 if (retval) {
10099 goto success;
10100 }
10101 }
10102 return PyErr_SetFromWindowsErr(err);
10103 }
10104
10105success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010106 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10107}
Larry Hastings2f936352014-08-05 14:04:04 +100010108#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010109
10110
Fred Drakec9680921999-12-13 16:37:25 +000010111/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10112 * It maps strings representing configuration variable names to
10113 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010114 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010115 * rarely-used constants. There are three separate tables that use
10116 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010117 *
10118 * This code is always included, even if none of the interfaces that
10119 * need it are included. The #if hackery needed to avoid it would be
10120 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010121 */
10122struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010123 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010124 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010125};
10126
Fred Drake12c6e2d1999-12-14 21:25:03 +000010127static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010128conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010129 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010130{
Christian Heimes217cfd12007-12-02 14:31:20 +000010131 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010132 int value = _PyLong_AsInt(arg);
10133 if (value == -1 && PyErr_Occurred())
10134 return 0;
10135 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010136 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010137 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010138 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010139 /* look up the value in the table using a binary search */
10140 size_t lo = 0;
10141 size_t mid;
10142 size_t hi = tablesize;
10143 int cmp;
10144 const char *confname;
10145 if (!PyUnicode_Check(arg)) {
10146 PyErr_SetString(PyExc_TypeError,
10147 "configuration names must be strings or integers");
10148 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010150 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010151 if (confname == NULL)
10152 return 0;
10153 while (lo < hi) {
10154 mid = (lo + hi) / 2;
10155 cmp = strcmp(confname, table[mid].name);
10156 if (cmp < 0)
10157 hi = mid;
10158 else if (cmp > 0)
10159 lo = mid + 1;
10160 else {
10161 *valuep = table[mid].value;
10162 return 1;
10163 }
10164 }
10165 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10166 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010168}
10169
10170
10171#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10172static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010173#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010175#endif
10176#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010178#endif
Fred Drakec9680921999-12-13 16:37:25 +000010179#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010224#ifdef _PC_ACL_ENABLED
10225 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10226#endif
10227#ifdef _PC_MIN_HOLE_SIZE
10228 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10229#endif
10230#ifdef _PC_ALLOC_SIZE_MIN
10231 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10232#endif
10233#ifdef _PC_REC_INCR_XFER_SIZE
10234 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10235#endif
10236#ifdef _PC_REC_MAX_XFER_SIZE
10237 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10238#endif
10239#ifdef _PC_REC_MIN_XFER_SIZE
10240 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10241#endif
10242#ifdef _PC_REC_XFER_ALIGN
10243 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10244#endif
10245#ifdef _PC_SYMLINK_MAX
10246 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10247#endif
10248#ifdef _PC_XATTR_ENABLED
10249 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10250#endif
10251#ifdef _PC_XATTR_EXISTS
10252 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10253#endif
10254#ifdef _PC_TIMESTAMP_RESOLUTION
10255 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10256#endif
Fred Drakec9680921999-12-13 16:37:25 +000010257};
10258
Fred Drakec9680921999-12-13 16:37:25 +000010259static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010260conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010261{
10262 return conv_confname(arg, valuep, posix_constants_pathconf,
10263 sizeof(posix_constants_pathconf)
10264 / sizeof(struct constdef));
10265}
10266#endif
10267
Larry Hastings2f936352014-08-05 14:04:04 +100010268
Fred Drakec9680921999-12-13 16:37:25 +000010269#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010270/*[clinic input]
10271os.fpathconf -> long
10272
10273 fd: int
10274 name: path_confname
10275 /
10276
10277Return the configuration limit name for the file descriptor fd.
10278
10279If there is no limit, return -1.
10280[clinic start generated code]*/
10281
Larry Hastings2f936352014-08-05 14:04:04 +100010282static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010283os_fpathconf_impl(PyObject *module, int fd, int name)
10284/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010285{
10286 long limit;
10287
10288 errno = 0;
10289 limit = fpathconf(fd, name);
10290 if (limit == -1 && errno != 0)
10291 posix_error();
10292
10293 return limit;
10294}
10295#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010296
10297
10298#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010299/*[clinic input]
10300os.pathconf -> long
10301 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10302 name: path_confname
10303
10304Return the configuration limit name for the file or directory path.
10305
10306If there is no limit, return -1.
10307On some platforms, path may also be specified as an open file descriptor.
10308 If this functionality is unavailable, using it raises an exception.
10309[clinic start generated code]*/
10310
Larry Hastings2f936352014-08-05 14:04:04 +100010311static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010312os_pathconf_impl(PyObject *module, path_t *path, int name)
10313/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010314{
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010316
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010318#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010319 if (path->fd != -1)
10320 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010321 else
10322#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010323 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 if (limit == -1 && errno != 0) {
10325 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010326 /* could be a path or name problem */
10327 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010328 else
Larry Hastings2f936352014-08-05 14:04:04 +100010329 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 }
Larry Hastings2f936352014-08-05 14:04:04 +100010331
10332 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010333}
Larry Hastings2f936352014-08-05 14:04:04 +100010334#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010335
10336#ifdef HAVE_CONFSTR
10337static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010338#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010340#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010341#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010343#endif
10344#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010346#endif
Fred Draked86ed291999-12-15 15:34:33 +000010347#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010349#endif
10350#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010352#endif
10353#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010355#endif
10356#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010358#endif
Fred Drakec9680921999-12-13 16:37:25 +000010359#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
Fred Draked86ed291999-12-15 15:34:33 +000010383#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010385#endif
Fred Drakec9680921999-12-13 16:37:25 +000010386#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
Fred Draked86ed291999-12-15 15:34:33 +000010389#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010391#endif
10392#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010394#endif
10395#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010397#endif
10398#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010400#endif
Fred Drakec9680921999-12-13 16:37:25 +000010401#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010403#endif
10404#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010406#endif
10407#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010409#endif
10410#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010412#endif
10413#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010415#endif
10416#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010418#endif
10419#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010421#endif
10422#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010424#endif
10425#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010426 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010427#endif
10428#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010429 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010430#endif
10431#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010432 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010433#endif
10434#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010436#endif
10437#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010439#endif
10440#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010441 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010442#endif
10443#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010445#endif
10446#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010448#endif
Fred Draked86ed291999-12-15 15:34:33 +000010449#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010451#endif
10452#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010453 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010454#endif
10455#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010457#endif
10458#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010459 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010460#endif
10461#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010463#endif
10464#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010466#endif
10467#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010468 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010469#endif
10470#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010471 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010472#endif
10473#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010475#endif
10476#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010477 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010478#endif
10479#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010481#endif
10482#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010484#endif
10485#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010487#endif
Fred Drakec9680921999-12-13 16:37:25 +000010488};
10489
10490static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010491conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010492{
10493 return conv_confname(arg, valuep, posix_constants_confstr,
10494 sizeof(posix_constants_confstr)
10495 / sizeof(struct constdef));
10496}
10497
Larry Hastings2f936352014-08-05 14:04:04 +100010498
10499/*[clinic input]
10500os.confstr
10501
10502 name: confstr_confname
10503 /
10504
10505Return a string-valued system configuration variable.
10506[clinic start generated code]*/
10507
Larry Hastings2f936352014-08-05 14:04:04 +100010508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010509os_confstr_impl(PyObject *module, int name)
10510/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010511{
10512 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010513 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010514 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010515
Victor Stinnercb043522010-09-10 23:49:04 +000010516 errno = 0;
10517 len = confstr(name, buffer, sizeof(buffer));
10518 if (len == 0) {
10519 if (errno) {
10520 posix_error();
10521 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010522 }
10523 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010524 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010525 }
10526 }
Victor Stinnercb043522010-09-10 23:49:04 +000010527
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010528 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010529 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010530 char *buf = PyMem_Malloc(len);
10531 if (buf == NULL)
10532 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010533 len2 = confstr(name, buf, len);
10534 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010535 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010536 PyMem_Free(buf);
10537 }
10538 else
10539 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010540 return result;
10541}
Larry Hastings2f936352014-08-05 14:04:04 +100010542#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010543
10544
10545#ifdef HAVE_SYSCONF
10546static struct constdef posix_constants_sysconf[] = {
10547#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
Fred Draked86ed291999-12-15 15:34:33 +000010577#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010579#endif
10580#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010582#endif
Fred Drakec9680921999-12-13 16:37:25 +000010583#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010585#endif
Fred Drakec9680921999-12-13 16:37:25 +000010586#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010588#endif
10589#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010591#endif
10592#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010594#endif
10595#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010597#endif
10598#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010600#endif
Fred Draked86ed291999-12-15 15:34:33 +000010601#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010603#endif
Fred Drakec9680921999-12-13 16:37:25 +000010604#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010606#endif
10607#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010609#endif
10610#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010612#endif
10613#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010615#endif
10616#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010618#endif
Fred Draked86ed291999-12-15 15:34:33 +000010619#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010620 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010621#endif
Fred Drakec9680921999-12-13 16:37:25 +000010622#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010624#endif
10625#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010626 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010627#endif
10628#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010630#endif
10631#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010632 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010633#endif
10634#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010635 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010636#endif
10637#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010638 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010639#endif
10640#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010642#endif
10643#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010645#endif
10646#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010648#endif
10649#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010651#endif
10652#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010654#endif
10655#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010657#endif
10658#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010659 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010660#endif
10661#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010663#endif
10664#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010665 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010666#endif
10667#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010669#endif
10670#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010671 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010672#endif
10673#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010674 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010675#endif
10676#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010677 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010678#endif
10679#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010680 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010681#endif
10682#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010684#endif
10685#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010687#endif
10688#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010689 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010690#endif
Fred Draked86ed291999-12-15 15:34:33 +000010691#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010692 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010693#endif
Fred Drakec9680921999-12-13 16:37:25 +000010694#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010696#endif
10697#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010699#endif
10700#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010701 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010702#endif
Fred Draked86ed291999-12-15 15:34:33 +000010703#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010704 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010705#endif
Fred Drakec9680921999-12-13 16:37:25 +000010706#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010707 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010708#endif
Fred Draked86ed291999-12-15 15:34:33 +000010709#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010710 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010711#endif
10712#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010714#endif
Fred Drakec9680921999-12-13 16:37:25 +000010715#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010716 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010717#endif
10718#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010719 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010720#endif
10721#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010723#endif
10724#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010725 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010726#endif
Fred Draked86ed291999-12-15 15:34:33 +000010727#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010729#endif
Fred Drakec9680921999-12-13 16:37:25 +000010730#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010732#endif
10733#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010735#endif
10736#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010738#endif
10739#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010741#endif
10742#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010744#endif
10745#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010747#endif
10748#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010750#endif
Fred Draked86ed291999-12-15 15:34:33 +000010751#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010753#endif
Fred Drakec9680921999-12-13 16:37:25 +000010754#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010756#endif
10757#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010759#endif
Fred Draked86ed291999-12-15 15:34:33 +000010760#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010762#endif
Fred Drakec9680921999-12-13 16:37:25 +000010763#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010765#endif
10766#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010768#endif
10769#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010771#endif
10772#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010774#endif
10775#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010776 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010777#endif
10778#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010780#endif
10781#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010783#endif
10784#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010786#endif
10787#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010789#endif
Fred Draked86ed291999-12-15 15:34:33 +000010790#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010791 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010792#endif
10793#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010795#endif
Fred Drakec9680921999-12-13 16:37:25 +000010796#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010797 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010798#endif
10799#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010801#endif
10802#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010804#endif
10805#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010806 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010807#endif
10808#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010810#endif
10811#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010813#endif
10814#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010815 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010816#endif
10817#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010819#endif
10820#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010822#endif
10823#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010825#endif
10826#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010828#endif
10829#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010831#endif
10832#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010834#endif
10835#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010837#endif
10838#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010840#endif
10841#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010843#endif
10844#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010846#endif
10847#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010849#endif
10850#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010851 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010852#endif
10853#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010855#endif
10856#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010858#endif
10859#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010861#endif
10862#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010864#endif
10865#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010867#endif
10868#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010870#endif
10871#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010873#endif
10874#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010876#endif
10877#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010879#endif
10880#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010882#endif
10883#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010885#endif
10886#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010888#endif
10889#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010891#endif
10892#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010894#endif
10895#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010897#endif
10898#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010900#endif
Fred Draked86ed291999-12-15 15:34:33 +000010901#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010903#endif
Fred Drakec9680921999-12-13 16:37:25 +000010904#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010906#endif
10907#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010909#endif
10910#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010912#endif
10913#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010915#endif
10916#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010918#endif
10919#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010921#endif
10922#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010924#endif
10925#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010927#endif
10928#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010930#endif
10931#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010933#endif
10934#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010936#endif
10937#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010939#endif
10940#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010942#endif
10943#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010945#endif
10946#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010948#endif
10949#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010951#endif
10952#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010954#endif
10955#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010957#endif
10958#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010960#endif
10961#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010963#endif
10964#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010965 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010966#endif
10967#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010969#endif
10970#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010972#endif
10973#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010975#endif
10976#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010978#endif
10979#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010981#endif
10982#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010984#endif
10985#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010987#endif
10988#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010990#endif
10991#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010993#endif
10994#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010996#endif
10997#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010999#endif
11000#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011002#endif
11003#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011005#endif
11006#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011008#endif
11009#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011011#endif
11012#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011014#endif
11015#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011017#endif
11018#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011020#endif
11021#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011023#endif
11024#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011026#endif
11027#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011028 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011029#endif
11030#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011032#endif
11033#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011035#endif
11036#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011038#endif
11039};
11040
11041static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011042conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011043{
11044 return conv_confname(arg, valuep, posix_constants_sysconf,
11045 sizeof(posix_constants_sysconf)
11046 / sizeof(struct constdef));
11047}
11048
Larry Hastings2f936352014-08-05 14:04:04 +100011049
11050/*[clinic input]
11051os.sysconf -> long
11052 name: sysconf_confname
11053 /
11054
11055Return an integer-valued system configuration variable.
11056[clinic start generated code]*/
11057
Larry Hastings2f936352014-08-05 14:04:04 +100011058static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011059os_sysconf_impl(PyObject *module, int name)
11060/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011061{
11062 long value;
11063
11064 errno = 0;
11065 value = sysconf(name);
11066 if (value == -1 && errno != 0)
11067 posix_error();
11068 return value;
11069}
11070#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011071
11072
Fred Drakebec628d1999-12-15 18:31:10 +000011073/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011074 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011075 * the exported dictionaries that are used to publish information about the
11076 * names available on the host platform.
11077 *
11078 * Sorting the table at runtime ensures that the table is properly ordered
11079 * when used, even for platforms we're not able to test on. It also makes
11080 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011081 */
Fred Drakebec628d1999-12-15 18:31:10 +000011082
11083static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011084cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011085{
11086 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011088 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011090
11091 return strcmp(c1->name, c2->name);
11092}
11093
11094static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011095setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011096 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011097{
Fred Drakebec628d1999-12-15 18:31:10 +000011098 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011099 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011100
11101 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11102 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011103 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011105
Barry Warsaw3155db32000-04-13 15:20:40 +000011106 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 PyObject *o = PyLong_FromLong(table[i].value);
11108 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11109 Py_XDECREF(o);
11110 Py_DECREF(d);
11111 return -1;
11112 }
11113 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011114 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011115 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011116}
11117
Fred Drakebec628d1999-12-15 18:31:10 +000011118/* Return -1 on failure, 0 on success. */
11119static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011120setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011121{
11122#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011123 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011124 sizeof(posix_constants_pathconf)
11125 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011126 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011127 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011128#endif
11129#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011130 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011131 sizeof(posix_constants_confstr)
11132 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011133 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011134 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011135#endif
11136#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011137 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011138 sizeof(posix_constants_sysconf)
11139 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011140 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011141 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011142#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011143 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011144}
Fred Draked86ed291999-12-15 15:34:33 +000011145
11146
Larry Hastings2f936352014-08-05 14:04:04 +100011147/*[clinic input]
11148os.abort
11149
11150Abort the interpreter immediately.
11151
11152This function 'dumps core' or otherwise fails in the hardest way possible
11153on the hosting operating system. This function never returns.
11154[clinic start generated code]*/
11155
Larry Hastings2f936352014-08-05 14:04:04 +100011156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011157os_abort_impl(PyObject *module)
11158/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011159{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011160 abort();
11161 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011162#ifndef __clang__
11163 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11164 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11165 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011166 Py_FatalError("abort() called from Python code didn't abort!");
11167 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011168#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011169}
Fred Drakebec628d1999-12-15 18:31:10 +000011170
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011171#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011172/* Grab ShellExecute dynamically from shell32 */
11173static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011174static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11175 LPCWSTR, INT);
11176static int
11177check_ShellExecute()
11178{
11179 HINSTANCE hShell32;
11180
11181 /* only recheck */
11182 if (-1 == has_ShellExecute) {
11183 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011184 /* Security note: this call is not vulnerable to "DLL hijacking".
11185 SHELL32 is part of "KnownDLLs" and so Windows always load
11186 the system SHELL32.DLL, even if there is another SHELL32.DLL
11187 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011188 hShell32 = LoadLibraryW(L"SHELL32");
11189 Py_END_ALLOW_THREADS
11190 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011191 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11192 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011193 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011194 } else {
11195 has_ShellExecute = 0;
11196 }
11197 }
11198 return has_ShellExecute;
11199}
11200
11201
Steve Dowercc16be82016-09-08 10:35:16 -070011202/*[clinic input]
11203os.startfile
11204 filepath: path_t
11205 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011206
Steve Dowercc16be82016-09-08 10:35:16 -070011207startfile(filepath [, operation])
11208
11209Start a file with its associated application.
11210
11211When "operation" is not specified or "open", this acts like
11212double-clicking the file in Explorer, or giving the file name as an
11213argument to the DOS "start" command: the file is opened with whatever
11214application (if any) its extension is associated.
11215When another "operation" is given, it specifies what should be done with
11216the file. A typical operation is "print".
11217
11218startfile returns as soon as the associated application is launched.
11219There is no option to wait for the application to close, and no way
11220to retrieve the application's exit status.
11221
11222The filepath is relative to the current directory. If you want to use
11223an absolute path, make sure the first character is not a slash ("/");
11224the underlying Win32 ShellExecute function doesn't work if it is.
11225[clinic start generated code]*/
11226
11227static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011228os_startfile_impl(PyObject *module, path_t *filepath,
11229 const Py_UNICODE *operation)
11230/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011231{
11232 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011233
11234 if(!check_ShellExecute()) {
11235 /* If the OS doesn't have ShellExecute, return a
11236 NotImplementedError. */
11237 return PyErr_Format(PyExc_NotImplementedError,
11238 "startfile not available on this platform");
11239 }
11240
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011242 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011243 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 Py_END_ALLOW_THREADS
11245
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011247 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011248 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 }
Steve Dowercc16be82016-09-08 10:35:16 -070011250 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011251}
Larry Hastings2f936352014-08-05 14:04:04 +100011252#endif /* MS_WINDOWS */
11253
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011254
Martin v. Löwis438b5342002-12-27 10:16:42 +000011255#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011256/*[clinic input]
11257os.getloadavg
11258
11259Return average recent system load information.
11260
11261Return the number of processes in the system run queue averaged over
11262the last 1, 5, and 15 minutes as a tuple of three floats.
11263Raises OSError if the load average was unobtainable.
11264[clinic start generated code]*/
11265
Larry Hastings2f936352014-08-05 14:04:04 +100011266static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011267os_getloadavg_impl(PyObject *module)
11268/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011269{
11270 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011271 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011272 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11273 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011274 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011275 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011276}
Larry Hastings2f936352014-08-05 14:04:04 +100011277#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011278
Larry Hastings2f936352014-08-05 14:04:04 +100011279
11280/*[clinic input]
11281os.device_encoding
11282 fd: int
11283
11284Return a string describing the encoding of a terminal's file descriptor.
11285
11286The file descriptor must be attached to a terminal.
11287If the device is not a terminal, return None.
11288[clinic start generated code]*/
11289
Larry Hastings2f936352014-08-05 14:04:04 +100011290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011291os_device_encoding_impl(PyObject *module, int fd)
11292/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011293{
Brett Cannonefb00c02012-02-29 18:31:31 -050011294 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011295}
11296
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011297
Larry Hastings2f936352014-08-05 14:04:04 +100011298#ifdef HAVE_SETRESUID
11299/*[clinic input]
11300os.setresuid
11301
11302 ruid: uid_t
11303 euid: uid_t
11304 suid: uid_t
11305 /
11306
11307Set the current process's real, effective, and saved user ids.
11308[clinic start generated code]*/
11309
Larry Hastings2f936352014-08-05 14:04:04 +100011310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011311os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11312/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011313{
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 if (setresuid(ruid, euid, suid) < 0)
11315 return posix_error();
11316 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011317}
Larry Hastings2f936352014-08-05 14:04:04 +100011318#endif /* HAVE_SETRESUID */
11319
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011320
11321#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011322/*[clinic input]
11323os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011324
Larry Hastings2f936352014-08-05 14:04:04 +100011325 rgid: gid_t
11326 egid: gid_t
11327 sgid: gid_t
11328 /
11329
11330Set the current process's real, effective, and saved group ids.
11331[clinic start generated code]*/
11332
Larry Hastings2f936352014-08-05 14:04:04 +100011333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011334os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11335/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011336{
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 if (setresgid(rgid, egid, sgid) < 0)
11338 return posix_error();
11339 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011340}
Larry Hastings2f936352014-08-05 14:04:04 +100011341#endif /* HAVE_SETRESGID */
11342
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011343
11344#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011345/*[clinic input]
11346os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011347
Larry Hastings2f936352014-08-05 14:04:04 +100011348Return a tuple of the current process's real, effective, and saved user ids.
11349[clinic start generated code]*/
11350
Larry Hastings2f936352014-08-05 14:04:04 +100011351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011352os_getresuid_impl(PyObject *module)
11353/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011354{
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 if (getresuid(&ruid, &euid, &suid) < 0)
11357 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011358 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11359 _PyLong_FromUid(euid),
11360 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011361}
Larry Hastings2f936352014-08-05 14:04:04 +100011362#endif /* HAVE_GETRESUID */
11363
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011364
11365#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011366/*[clinic input]
11367os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011368
Larry Hastings2f936352014-08-05 14:04:04 +100011369Return a tuple of the current process's real, effective, and saved group ids.
11370[clinic start generated code]*/
11371
Larry Hastings2f936352014-08-05 14:04:04 +100011372static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011373os_getresgid_impl(PyObject *module)
11374/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011375{
11376 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 if (getresgid(&rgid, &egid, &sgid) < 0)
11378 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011379 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11380 _PyLong_FromGid(egid),
11381 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011382}
Larry Hastings2f936352014-08-05 14:04:04 +100011383#endif /* HAVE_GETRESGID */
11384
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011385
Benjamin Peterson9428d532011-09-14 11:45:52 -040011386#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011387/*[clinic input]
11388os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011389
Larry Hastings2f936352014-08-05 14:04:04 +100011390 path: path_t(allow_fd=True)
11391 attribute: path_t
11392 *
11393 follow_symlinks: bool = True
11394
11395Return the value of extended attribute attribute on path.
11396
BNMetricsb9427072018-11-02 15:20:19 +000011397path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011398If follow_symlinks is False, and the last element of the path is a symbolic
11399 link, getxattr will examine the symbolic link itself instead of the file
11400 the link points to.
11401
11402[clinic start generated code]*/
11403
Larry Hastings2f936352014-08-05 14:04:04 +100011404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011405os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011406 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011407/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011408{
11409 Py_ssize_t i;
11410 PyObject *buffer = NULL;
11411
11412 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11413 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011414
Larry Hastings9cf065c2012-06-22 16:30:09 -070011415 for (i = 0; ; i++) {
11416 void *ptr;
11417 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011418 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011419 Py_ssize_t buffer_size = buffer_sizes[i];
11420 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011421 path_error(path);
11422 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011423 }
11424 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11425 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011426 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011427 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011428
Larry Hastings9cf065c2012-06-22 16:30:09 -070011429 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011430 if (path->fd >= 0)
11431 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011432 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011433 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011434 else
Larry Hastings2f936352014-08-05 14:04:04 +100011435 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011436 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011437
Larry Hastings9cf065c2012-06-22 16:30:09 -070011438 if (result < 0) {
11439 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011440 if (errno == ERANGE)
11441 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011442 path_error(path);
11443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011444 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011445
Larry Hastings9cf065c2012-06-22 16:30:09 -070011446 if (result != buffer_size) {
11447 /* Can only shrink. */
11448 _PyBytes_Resize(&buffer, result);
11449 }
11450 break;
11451 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011452
Larry Hastings9cf065c2012-06-22 16:30:09 -070011453 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011454}
11455
Larry Hastings2f936352014-08-05 14:04:04 +100011456
11457/*[clinic input]
11458os.setxattr
11459
11460 path: path_t(allow_fd=True)
11461 attribute: path_t
11462 value: Py_buffer
11463 flags: int = 0
11464 *
11465 follow_symlinks: bool = True
11466
11467Set extended attribute attribute on path to value.
11468
BNMetricsb9427072018-11-02 15:20:19 +000011469path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011470If follow_symlinks is False, and the last element of the path is a symbolic
11471 link, setxattr will modify the symbolic link itself instead of the file
11472 the link points to.
11473
11474[clinic start generated code]*/
11475
Benjamin Peterson799bd802011-08-31 22:15:17 -040011476static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011477os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011478 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011479/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011480{
Larry Hastings2f936352014-08-05 14:04:04 +100011481 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011482
Larry Hastings2f936352014-08-05 14:04:04 +100011483 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011484 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011485
Benjamin Peterson799bd802011-08-31 22:15:17 -040011486 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011487 if (path->fd > -1)
11488 result = fsetxattr(path->fd, attribute->narrow,
11489 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011490 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011491 result = setxattr(path->narrow, attribute->narrow,
11492 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011493 else
Larry Hastings2f936352014-08-05 14:04:04 +100011494 result = lsetxattr(path->narrow, attribute->narrow,
11495 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011496 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011497
Larry Hastings9cf065c2012-06-22 16:30:09 -070011498 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011499 path_error(path);
11500 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011501 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011502
Larry Hastings2f936352014-08-05 14:04:04 +100011503 Py_RETURN_NONE;
11504}
11505
11506
11507/*[clinic input]
11508os.removexattr
11509
11510 path: path_t(allow_fd=True)
11511 attribute: path_t
11512 *
11513 follow_symlinks: bool = True
11514
11515Remove extended attribute attribute on path.
11516
BNMetricsb9427072018-11-02 15:20:19 +000011517path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011518If follow_symlinks is False, and the last element of the path is a symbolic
11519 link, removexattr will modify the symbolic link itself instead of the file
11520 the link points to.
11521
11522[clinic start generated code]*/
11523
Larry Hastings2f936352014-08-05 14:04:04 +100011524static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011525os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011526 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011527/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011528{
11529 ssize_t result;
11530
11531 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11532 return NULL;
11533
11534 Py_BEGIN_ALLOW_THREADS;
11535 if (path->fd > -1)
11536 result = fremovexattr(path->fd, attribute->narrow);
11537 else if (follow_symlinks)
11538 result = removexattr(path->narrow, attribute->narrow);
11539 else
11540 result = lremovexattr(path->narrow, attribute->narrow);
11541 Py_END_ALLOW_THREADS;
11542
11543 if (result) {
11544 return path_error(path);
11545 }
11546
11547 Py_RETURN_NONE;
11548}
11549
11550
11551/*[clinic input]
11552os.listxattr
11553
11554 path: path_t(allow_fd=True, nullable=True) = None
11555 *
11556 follow_symlinks: bool = True
11557
11558Return a list of extended attributes on path.
11559
BNMetricsb9427072018-11-02 15:20:19 +000011560path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011561if path is None, listxattr will examine the current directory.
11562If follow_symlinks is False, and the last element of the path is a symbolic
11563 link, listxattr will examine the symbolic link itself instead of the file
11564 the link points to.
11565[clinic start generated code]*/
11566
Larry Hastings2f936352014-08-05 14:04:04 +100011567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011568os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011569/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011570{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011571 Py_ssize_t i;
11572 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011573 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011574 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011575
Larry Hastings2f936352014-08-05 14:04:04 +100011576 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011577 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011578
Larry Hastings2f936352014-08-05 14:04:04 +100011579 name = path->narrow ? path->narrow : ".";
11580
Larry Hastings9cf065c2012-06-22 16:30:09 -070011581 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011582 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011583 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011584 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011585 Py_ssize_t buffer_size = buffer_sizes[i];
11586 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011587 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011588 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011589 break;
11590 }
11591 buffer = PyMem_MALLOC(buffer_size);
11592 if (!buffer) {
11593 PyErr_NoMemory();
11594 break;
11595 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011596
Larry Hastings9cf065c2012-06-22 16:30:09 -070011597 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011598 if (path->fd > -1)
11599 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011600 else if (follow_symlinks)
11601 length = listxattr(name, buffer, buffer_size);
11602 else
11603 length = llistxattr(name, buffer, buffer_size);
11604 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011605
Larry Hastings9cf065c2012-06-22 16:30:09 -070011606 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011607 if (errno == ERANGE) {
11608 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011609 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011610 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011611 }
Larry Hastings2f936352014-08-05 14:04:04 +100011612 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011613 break;
11614 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011615
Larry Hastings9cf065c2012-06-22 16:30:09 -070011616 result = PyList_New(0);
11617 if (!result) {
11618 goto exit;
11619 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011620
Larry Hastings9cf065c2012-06-22 16:30:09 -070011621 end = buffer + length;
11622 for (trace = start = buffer; trace != end; trace++) {
11623 if (!*trace) {
11624 int error;
11625 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11626 trace - start);
11627 if (!attribute) {
11628 Py_DECREF(result);
11629 result = NULL;
11630 goto exit;
11631 }
11632 error = PyList_Append(result, attribute);
11633 Py_DECREF(attribute);
11634 if (error) {
11635 Py_DECREF(result);
11636 result = NULL;
11637 goto exit;
11638 }
11639 start = trace + 1;
11640 }
11641 }
11642 break;
11643 }
11644exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011645 if (buffer)
11646 PyMem_FREE(buffer);
11647 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011648}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011649#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011650
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011651
Larry Hastings2f936352014-08-05 14:04:04 +100011652/*[clinic input]
11653os.urandom
11654
11655 size: Py_ssize_t
11656 /
11657
11658Return a bytes object containing random bytes suitable for cryptographic use.
11659[clinic start generated code]*/
11660
Larry Hastings2f936352014-08-05 14:04:04 +100011661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011662os_urandom_impl(PyObject *module, Py_ssize_t size)
11663/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011664{
11665 PyObject *bytes;
11666 int result;
11667
Georg Brandl2fb477c2012-02-21 00:33:36 +010011668 if (size < 0)
11669 return PyErr_Format(PyExc_ValueError,
11670 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011671 bytes = PyBytes_FromStringAndSize(NULL, size);
11672 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011673 return NULL;
11674
Victor Stinnere66987e2016-09-06 16:33:52 -070011675 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011676 if (result == -1) {
11677 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011678 return NULL;
11679 }
Larry Hastings2f936352014-08-05 14:04:04 +100011680 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011681}
11682
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011683/* Terminal size querying */
11684
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011685static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011686
11687PyDoc_STRVAR(TerminalSize_docstring,
11688 "A tuple of (columns, lines) for holding terminal window size");
11689
11690static PyStructSequence_Field TerminalSize_fields[] = {
11691 {"columns", "width of the terminal window in characters"},
11692 {"lines", "height of the terminal window in characters"},
11693 {NULL, NULL}
11694};
11695
11696static PyStructSequence_Desc TerminalSize_desc = {
11697 "os.terminal_size",
11698 TerminalSize_docstring,
11699 TerminalSize_fields,
11700 2,
11701};
11702
11703#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011704/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011705PyDoc_STRVAR(termsize__doc__,
11706 "Return the size of the terminal window as (columns, lines).\n" \
11707 "\n" \
11708 "The optional argument fd (default standard output) specifies\n" \
11709 "which file descriptor should be queried.\n" \
11710 "\n" \
11711 "If the file descriptor is not connected to a terminal, an OSError\n" \
11712 "is thrown.\n" \
11713 "\n" \
11714 "This function will only be defined if an implementation is\n" \
11715 "available for this system.\n" \
11716 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011717 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011718 "normally be used, os.get_terminal_size is the low-level implementation.");
11719
11720static PyObject*
11721get_terminal_size(PyObject *self, PyObject *args)
11722{
11723 int columns, lines;
11724 PyObject *termsize;
11725
11726 int fd = fileno(stdout);
11727 /* Under some conditions stdout may not be connected and
11728 * fileno(stdout) may point to an invalid file descriptor. For example
11729 * GUI apps don't have valid standard streams by default.
11730 *
11731 * If this happens, and the optional fd argument is not present,
11732 * the ioctl below will fail returning EBADF. This is what we want.
11733 */
11734
11735 if (!PyArg_ParseTuple(args, "|i", &fd))
11736 return NULL;
11737
11738#ifdef TERMSIZE_USE_IOCTL
11739 {
11740 struct winsize w;
11741 if (ioctl(fd, TIOCGWINSZ, &w))
11742 return PyErr_SetFromErrno(PyExc_OSError);
11743 columns = w.ws_col;
11744 lines = w.ws_row;
11745 }
11746#endif /* TERMSIZE_USE_IOCTL */
11747
11748#ifdef TERMSIZE_USE_CONIO
11749 {
11750 DWORD nhandle;
11751 HANDLE handle;
11752 CONSOLE_SCREEN_BUFFER_INFO csbi;
11753 switch (fd) {
11754 case 0: nhandle = STD_INPUT_HANDLE;
11755 break;
11756 case 1: nhandle = STD_OUTPUT_HANDLE;
11757 break;
11758 case 2: nhandle = STD_ERROR_HANDLE;
11759 break;
11760 default:
11761 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11762 }
11763 handle = GetStdHandle(nhandle);
11764 if (handle == NULL)
11765 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11766 if (handle == INVALID_HANDLE_VALUE)
11767 return PyErr_SetFromWindowsErr(0);
11768
11769 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11770 return PyErr_SetFromWindowsErr(0);
11771
11772 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11773 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11774 }
11775#endif /* TERMSIZE_USE_CONIO */
11776
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011777 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011778 if (termsize == NULL)
11779 return NULL;
11780 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11781 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11782 if (PyErr_Occurred()) {
11783 Py_DECREF(termsize);
11784 return NULL;
11785 }
11786 return termsize;
11787}
11788#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11789
Larry Hastings2f936352014-08-05 14:04:04 +100011790
11791/*[clinic input]
11792os.cpu_count
11793
Charles-François Natali80d62e62015-08-13 20:37:08 +010011794Return the number of CPUs in the system; return None if indeterminable.
11795
11796This number is not equivalent to the number of CPUs the current process can
11797use. The number of usable CPUs can be obtained with
11798``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011799[clinic start generated code]*/
11800
Larry Hastings2f936352014-08-05 14:04:04 +100011801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011802os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011803/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011804{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011805 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011806#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011807 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11808 Need to fallback to Vista behavior if this call isn't present */
11809 HINSTANCE hKernel32;
11810 hKernel32 = GetModuleHandleW(L"KERNEL32");
11811
11812 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11813 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11814 "GetMaximumProcessorCount");
11815 if (_GetMaximumProcessorCount != NULL) {
11816 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11817 }
11818 else {
11819 SYSTEM_INFO sysinfo;
11820 GetSystemInfo(&sysinfo);
11821 ncpu = sysinfo.dwNumberOfProcessors;
11822 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011823#elif defined(__hpux)
11824 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11825#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11826 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011827#elif defined(__DragonFly__) || \
11828 defined(__OpenBSD__) || \
11829 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011830 defined(__NetBSD__) || \
11831 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011832 int mib[2];
11833 size_t len = sizeof(ncpu);
11834 mib[0] = CTL_HW;
11835 mib[1] = HW_NCPU;
11836 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11837 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011838#endif
11839 if (ncpu >= 1)
11840 return PyLong_FromLong(ncpu);
11841 else
11842 Py_RETURN_NONE;
11843}
11844
Victor Stinnerdaf45552013-08-28 00:53:59 +020011845
Larry Hastings2f936352014-08-05 14:04:04 +100011846/*[clinic input]
11847os.get_inheritable -> bool
11848
11849 fd: int
11850 /
11851
11852Get the close-on-exe flag of the specified file descriptor.
11853[clinic start generated code]*/
11854
Larry Hastings2f936352014-08-05 14:04:04 +100011855static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011856os_get_inheritable_impl(PyObject *module, int fd)
11857/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011858{
Steve Dower8fc89802015-04-12 00:26:27 -040011859 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011860 _Py_BEGIN_SUPPRESS_IPH
11861 return_value = _Py_get_inheritable(fd);
11862 _Py_END_SUPPRESS_IPH
11863 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011864}
11865
11866
11867/*[clinic input]
11868os.set_inheritable
11869 fd: int
11870 inheritable: int
11871 /
11872
11873Set the inheritable flag of the specified file descriptor.
11874[clinic start generated code]*/
11875
Larry Hastings2f936352014-08-05 14:04:04 +100011876static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011877os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11878/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011879{
Steve Dower8fc89802015-04-12 00:26:27 -040011880 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011881
Steve Dower8fc89802015-04-12 00:26:27 -040011882 _Py_BEGIN_SUPPRESS_IPH
11883 result = _Py_set_inheritable(fd, inheritable, NULL);
11884 _Py_END_SUPPRESS_IPH
11885 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011886 return NULL;
11887 Py_RETURN_NONE;
11888}
11889
11890
11891#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011892/*[clinic input]
11893os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011894 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011895 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011896
Larry Hastings2f936352014-08-05 14:04:04 +100011897Get the close-on-exe flag of the specified file descriptor.
11898[clinic start generated code]*/
11899
Larry Hastings2f936352014-08-05 14:04:04 +100011900static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011901os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011902/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011903{
11904 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011905
11906 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11907 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011908 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011909 }
11910
Larry Hastings2f936352014-08-05 14:04:04 +100011911 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011912}
11913
Victor Stinnerdaf45552013-08-28 00:53:59 +020011914
Larry Hastings2f936352014-08-05 14:04:04 +100011915/*[clinic input]
11916os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011917 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011918 inheritable: bool
11919 /
11920
11921Set the inheritable flag of the specified handle.
11922[clinic start generated code]*/
11923
Larry Hastings2f936352014-08-05 14:04:04 +100011924static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011925os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011926 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011927/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011928{
11929 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011930 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11931 PyErr_SetFromWindowsErr(0);
11932 return NULL;
11933 }
11934 Py_RETURN_NONE;
11935}
Larry Hastings2f936352014-08-05 14:04:04 +100011936#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011937
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011938#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011939/*[clinic input]
11940os.get_blocking -> bool
11941 fd: int
11942 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011943
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011944Get the blocking mode of the file descriptor.
11945
11946Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
11947[clinic start generated code]*/
11948
11949static int
11950os_get_blocking_impl(PyObject *module, int fd)
11951/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011952{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011953 int blocking;
11954
Steve Dower8fc89802015-04-12 00:26:27 -040011955 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011956 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011957 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011958 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011959}
11960
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011961/*[clinic input]
11962os.set_blocking
11963 fd: int
11964 blocking: bool(accept={int})
11965 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011966
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011967Set the blocking mode of the specified file descriptor.
11968
11969Set the O_NONBLOCK flag if blocking is False,
11970clear the O_NONBLOCK flag otherwise.
11971[clinic start generated code]*/
11972
11973static PyObject *
11974os_set_blocking_impl(PyObject *module, int fd, int blocking)
11975/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011976{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011977 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011978
Steve Dower8fc89802015-04-12 00:26:27 -040011979 _Py_BEGIN_SUPPRESS_IPH
11980 result = _Py_set_blocking(fd, blocking);
11981 _Py_END_SUPPRESS_IPH
11982 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011983 return NULL;
11984 Py_RETURN_NONE;
11985}
11986#endif /* !MS_WINDOWS */
11987
11988
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011989/*[clinic input]
11990class os.DirEntry "DirEntry *" "&DirEntryType"
11991[clinic start generated code]*/
11992/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011993
11994typedef struct {
11995 PyObject_HEAD
11996 PyObject *name;
11997 PyObject *path;
11998 PyObject *stat;
11999 PyObject *lstat;
12000#ifdef MS_WINDOWS
12001 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012002 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012003 int got_file_index;
12004#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012005#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012006 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012007#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012008 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012009 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012010#endif
12011} DirEntry;
12012
12013static void
12014DirEntry_dealloc(DirEntry *entry)
12015{
12016 Py_XDECREF(entry->name);
12017 Py_XDECREF(entry->path);
12018 Py_XDECREF(entry->stat);
12019 Py_XDECREF(entry->lstat);
12020 Py_TYPE(entry)->tp_free((PyObject *)entry);
12021}
12022
12023/* Forward reference */
12024static int
12025DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12026
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012027/*[clinic input]
12028os.DirEntry.is_symlink -> bool
12029
12030Return True if the entry is a symbolic link; cached per entry.
12031[clinic start generated code]*/
12032
Victor Stinner6036e442015-03-08 01:58:04 +010012033static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012034os_DirEntry_is_symlink_impl(DirEntry *self)
12035/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012036{
12037#ifdef MS_WINDOWS
12038 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012039#elif defined(HAVE_DIRENT_D_TYPE)
12040 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012041 if (self->d_type != DT_UNKNOWN)
12042 return self->d_type == DT_LNK;
12043 else
12044 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012045#else
12046 /* POSIX without d_type */
12047 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012048#endif
12049}
12050
12051static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012052DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12053{
12054 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012055 STRUCT_STAT st;
12056 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012057
12058#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012059 if (!PyUnicode_FSDecoder(self->path, &ub))
12060 return NULL;
12061 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012062#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012063 if (!PyUnicode_FSConverter(self->path, &ub))
12064 return NULL;
12065 const char *path = PyBytes_AS_STRING(ub);
12066 if (self->dir_fd != DEFAULT_DIR_FD) {
12067#ifdef HAVE_FSTATAT
12068 result = fstatat(self->dir_fd, path, &st,
12069 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12070#else
12071 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12072 return NULL;
12073#endif /* HAVE_FSTATAT */
12074 }
12075 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012076#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012077 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012078 if (follow_symlinks)
12079 result = STAT(path, &st);
12080 else
12081 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012082 }
12083 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012084
12085 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012086 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012087
12088 return _pystat_fromstructstat(&st);
12089}
12090
12091static PyObject *
12092DirEntry_get_lstat(DirEntry *self)
12093{
12094 if (!self->lstat) {
12095#ifdef MS_WINDOWS
12096 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12097#else /* POSIX */
12098 self->lstat = DirEntry_fetch_stat(self, 0);
12099#endif
12100 }
12101 Py_XINCREF(self->lstat);
12102 return self->lstat;
12103}
12104
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012105/*[clinic input]
12106os.DirEntry.stat
12107 *
12108 follow_symlinks: bool = True
12109
12110Return stat_result object for the entry; cached per entry.
12111[clinic start generated code]*/
12112
Victor Stinner6036e442015-03-08 01:58:04 +010012113static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012114os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12115/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012116{
12117 if (!follow_symlinks)
12118 return DirEntry_get_lstat(self);
12119
12120 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012121 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012122 if (result == -1)
12123 return NULL;
12124 else if (result)
12125 self->stat = DirEntry_fetch_stat(self, 1);
12126 else
12127 self->stat = DirEntry_get_lstat(self);
12128 }
12129
12130 Py_XINCREF(self->stat);
12131 return self->stat;
12132}
12133
Victor Stinner6036e442015-03-08 01:58:04 +010012134/* Set exception and return -1 on error, 0 for False, 1 for True */
12135static int
12136DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12137{
12138 PyObject *stat = NULL;
12139 PyObject *st_mode = NULL;
12140 long mode;
12141 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012142#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012143 int is_symlink;
12144 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012145#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012146#ifdef MS_WINDOWS
12147 unsigned long dir_bits;
12148#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012149 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012150
12151#ifdef MS_WINDOWS
12152 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12153 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012154#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012155 is_symlink = self->d_type == DT_LNK;
12156 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12157#endif
12158
Victor Stinner35a97c02015-03-08 02:59:09 +010012159#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012160 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012161#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012162 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012163 if (!stat) {
12164 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12165 /* If file doesn't exist (anymore), then return False
12166 (i.e., say it's not a file/directory) */
12167 PyErr_Clear();
12168 return 0;
12169 }
12170 goto error;
12171 }
12172 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12173 if (!st_mode)
12174 goto error;
12175
12176 mode = PyLong_AsLong(st_mode);
12177 if (mode == -1 && PyErr_Occurred())
12178 goto error;
12179 Py_CLEAR(st_mode);
12180 Py_CLEAR(stat);
12181 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012182#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012183 }
12184 else if (is_symlink) {
12185 assert(mode_bits != S_IFLNK);
12186 result = 0;
12187 }
12188 else {
12189 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12190#ifdef MS_WINDOWS
12191 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12192 if (mode_bits == S_IFDIR)
12193 result = dir_bits != 0;
12194 else
12195 result = dir_bits == 0;
12196#else /* POSIX */
12197 if (mode_bits == S_IFDIR)
12198 result = self->d_type == DT_DIR;
12199 else
12200 result = self->d_type == DT_REG;
12201#endif
12202 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012203#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012204
12205 return result;
12206
12207error:
12208 Py_XDECREF(st_mode);
12209 Py_XDECREF(stat);
12210 return -1;
12211}
12212
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012213/*[clinic input]
12214os.DirEntry.is_dir -> bool
12215 *
12216 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012217
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012218Return True if the entry is a directory; cached per entry.
12219[clinic start generated code]*/
12220
12221static int
12222os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12223/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12224{
12225 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012226}
12227
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012228/*[clinic input]
12229os.DirEntry.is_file -> bool
12230 *
12231 follow_symlinks: bool = True
12232
12233Return True if the entry is a file; cached per entry.
12234[clinic start generated code]*/
12235
12236static int
12237os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12238/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012239{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012240 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012241}
12242
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012243/*[clinic input]
12244os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012245
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012246Return inode of the entry; cached per entry.
12247[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012248
12249static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012250os_DirEntry_inode_impl(DirEntry *self)
12251/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012252{
12253#ifdef MS_WINDOWS
12254 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012255 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012256 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012257 STRUCT_STAT stat;
12258 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012259
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012260 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012261 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012262 path = PyUnicode_AsUnicode(unicode);
12263 result = LSTAT(path, &stat);
12264 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012265
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012266 if (result != 0)
12267 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012268
12269 self->win32_file_index = stat.st_ino;
12270 self->got_file_index = 1;
12271 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012272 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12273 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012274#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012275 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12276 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012277#endif
12278}
12279
12280static PyObject *
12281DirEntry_repr(DirEntry *self)
12282{
12283 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12284}
12285
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012286/*[clinic input]
12287os.DirEntry.__fspath__
12288
12289Returns the path for the entry.
12290[clinic start generated code]*/
12291
Brett Cannon96881cd2016-06-10 14:37:21 -070012292static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012293os_DirEntry___fspath___impl(DirEntry *self)
12294/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012295{
12296 Py_INCREF(self->path);
12297 return self->path;
12298}
12299
Victor Stinner6036e442015-03-08 01:58:04 +010012300static PyMemberDef DirEntry_members[] = {
12301 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12302 "the entry's base filename, relative to scandir() \"path\" argument"},
12303 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12304 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12305 {NULL}
12306};
12307
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012308#include "clinic/posixmodule.c.h"
12309
Victor Stinner6036e442015-03-08 01:58:04 +010012310static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012311 OS_DIRENTRY_IS_DIR_METHODDEF
12312 OS_DIRENTRY_IS_FILE_METHODDEF
12313 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12314 OS_DIRENTRY_STAT_METHODDEF
12315 OS_DIRENTRY_INODE_METHODDEF
12316 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012317 {NULL}
12318};
12319
Benjamin Peterson5646de42015-04-12 17:56:34 -040012320static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012321 PyVarObject_HEAD_INIT(NULL, 0)
12322 MODNAME ".DirEntry", /* tp_name */
12323 sizeof(DirEntry), /* tp_basicsize */
12324 0, /* tp_itemsize */
12325 /* methods */
12326 (destructor)DirEntry_dealloc, /* tp_dealloc */
12327 0, /* tp_print */
12328 0, /* tp_getattr */
12329 0, /* tp_setattr */
12330 0, /* tp_compare */
12331 (reprfunc)DirEntry_repr, /* tp_repr */
12332 0, /* tp_as_number */
12333 0, /* tp_as_sequence */
12334 0, /* tp_as_mapping */
12335 0, /* tp_hash */
12336 0, /* tp_call */
12337 0, /* tp_str */
12338 0, /* tp_getattro */
12339 0, /* tp_setattro */
12340 0, /* tp_as_buffer */
12341 Py_TPFLAGS_DEFAULT, /* tp_flags */
12342 0, /* tp_doc */
12343 0, /* tp_traverse */
12344 0, /* tp_clear */
12345 0, /* tp_richcompare */
12346 0, /* tp_weaklistoffset */
12347 0, /* tp_iter */
12348 0, /* tp_iternext */
12349 DirEntry_methods, /* tp_methods */
12350 DirEntry_members, /* tp_members */
12351};
12352
12353#ifdef MS_WINDOWS
12354
12355static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012356join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012357{
12358 Py_ssize_t path_len;
12359 Py_ssize_t size;
12360 wchar_t *result;
12361 wchar_t ch;
12362
12363 if (!path_wide) { /* Default arg: "." */
12364 path_wide = L".";
12365 path_len = 1;
12366 }
12367 else {
12368 path_len = wcslen(path_wide);
12369 }
12370
12371 /* The +1's are for the path separator and the NUL */
12372 size = path_len + 1 + wcslen(filename) + 1;
12373 result = PyMem_New(wchar_t, size);
12374 if (!result) {
12375 PyErr_NoMemory();
12376 return NULL;
12377 }
12378 wcscpy(result, path_wide);
12379 if (path_len > 0) {
12380 ch = result[path_len - 1];
12381 if (ch != SEP && ch != ALTSEP && ch != L':')
12382 result[path_len++] = SEP;
12383 wcscpy(result + path_len, filename);
12384 }
12385 return result;
12386}
12387
12388static PyObject *
12389DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12390{
12391 DirEntry *entry;
12392 BY_HANDLE_FILE_INFORMATION file_info;
12393 ULONG reparse_tag;
12394 wchar_t *joined_path;
12395
12396 entry = PyObject_New(DirEntry, &DirEntryType);
12397 if (!entry)
12398 return NULL;
12399 entry->name = NULL;
12400 entry->path = NULL;
12401 entry->stat = NULL;
12402 entry->lstat = NULL;
12403 entry->got_file_index = 0;
12404
12405 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12406 if (!entry->name)
12407 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012408 if (path->narrow) {
12409 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12410 if (!entry->name)
12411 goto error;
12412 }
Victor Stinner6036e442015-03-08 01:58:04 +010012413
12414 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12415 if (!joined_path)
12416 goto error;
12417
12418 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12419 PyMem_Free(joined_path);
12420 if (!entry->path)
12421 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012422 if (path->narrow) {
12423 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12424 if (!entry->path)
12425 goto error;
12426 }
Victor Stinner6036e442015-03-08 01:58:04 +010012427
Steve Dowercc16be82016-09-08 10:35:16 -070012428 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012429 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12430
12431 return (PyObject *)entry;
12432
12433error:
12434 Py_DECREF(entry);
12435 return NULL;
12436}
12437
12438#else /* POSIX */
12439
12440static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012441join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012442{
12443 Py_ssize_t path_len;
12444 Py_ssize_t size;
12445 char *result;
12446
12447 if (!path_narrow) { /* Default arg: "." */
12448 path_narrow = ".";
12449 path_len = 1;
12450 }
12451 else {
12452 path_len = strlen(path_narrow);
12453 }
12454
12455 if (filename_len == -1)
12456 filename_len = strlen(filename);
12457
12458 /* The +1's are for the path separator and the NUL */
12459 size = path_len + 1 + filename_len + 1;
12460 result = PyMem_New(char, size);
12461 if (!result) {
12462 PyErr_NoMemory();
12463 return NULL;
12464 }
12465 strcpy(result, path_narrow);
12466 if (path_len > 0 && result[path_len - 1] != '/')
12467 result[path_len++] = '/';
12468 strcpy(result + path_len, filename);
12469 return result;
12470}
12471
12472static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012473DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012474 ino_t d_ino
12475#ifdef HAVE_DIRENT_D_TYPE
12476 , unsigned char d_type
12477#endif
12478 )
Victor Stinner6036e442015-03-08 01:58:04 +010012479{
12480 DirEntry *entry;
12481 char *joined_path;
12482
12483 entry = PyObject_New(DirEntry, &DirEntryType);
12484 if (!entry)
12485 return NULL;
12486 entry->name = NULL;
12487 entry->path = NULL;
12488 entry->stat = NULL;
12489 entry->lstat = NULL;
12490
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012491 if (path->fd != -1) {
12492 entry->dir_fd = path->fd;
12493 joined_path = NULL;
12494 }
12495 else {
12496 entry->dir_fd = DEFAULT_DIR_FD;
12497 joined_path = join_path_filename(path->narrow, name, name_len);
12498 if (!joined_path)
12499 goto error;
12500 }
Victor Stinner6036e442015-03-08 01:58:04 +010012501
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012502 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012503 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012504 if (joined_path)
12505 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012506 }
12507 else {
12508 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012509 if (joined_path)
12510 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012511 }
12512 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012513 if (!entry->name)
12514 goto error;
12515
12516 if (path->fd != -1) {
12517 entry->path = entry->name;
12518 Py_INCREF(entry->path);
12519 }
12520 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012521 goto error;
12522
Victor Stinner35a97c02015-03-08 02:59:09 +010012523#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012524 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012525#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012526 entry->d_ino = d_ino;
12527
12528 return (PyObject *)entry;
12529
12530error:
12531 Py_XDECREF(entry);
12532 return NULL;
12533}
12534
12535#endif
12536
12537
12538typedef struct {
12539 PyObject_HEAD
12540 path_t path;
12541#ifdef MS_WINDOWS
12542 HANDLE handle;
12543 WIN32_FIND_DATAW file_data;
12544 int first_time;
12545#else /* POSIX */
12546 DIR *dirp;
12547#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012548#ifdef HAVE_FDOPENDIR
12549 int fd;
12550#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012551} ScandirIterator;
12552
12553#ifdef MS_WINDOWS
12554
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012555static int
12556ScandirIterator_is_closed(ScandirIterator *iterator)
12557{
12558 return iterator->handle == INVALID_HANDLE_VALUE;
12559}
12560
Victor Stinner6036e442015-03-08 01:58:04 +010012561static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012562ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012563{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012564 HANDLE handle = iterator->handle;
12565
12566 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012567 return;
12568
Victor Stinner6036e442015-03-08 01:58:04 +010012569 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012570 Py_BEGIN_ALLOW_THREADS
12571 FindClose(handle);
12572 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012573}
12574
12575static PyObject *
12576ScandirIterator_iternext(ScandirIterator *iterator)
12577{
12578 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12579 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012580 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012581
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012582 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012583 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012584 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012585
12586 while (1) {
12587 if (!iterator->first_time) {
12588 Py_BEGIN_ALLOW_THREADS
12589 success = FindNextFileW(iterator->handle, file_data);
12590 Py_END_ALLOW_THREADS
12591 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012592 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012593 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012594 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012595 break;
12596 }
12597 }
12598 iterator->first_time = 0;
12599
12600 /* Skip over . and .. */
12601 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012602 wcscmp(file_data->cFileName, L"..") != 0) {
12603 entry = DirEntry_from_find_data(&iterator->path, file_data);
12604 if (!entry)
12605 break;
12606 return entry;
12607 }
Victor Stinner6036e442015-03-08 01:58:04 +010012608
12609 /* Loop till we get a non-dot directory or finish iterating */
12610 }
12611
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012612 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012613 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012614 return NULL;
12615}
12616
12617#else /* POSIX */
12618
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012619static int
12620ScandirIterator_is_closed(ScandirIterator *iterator)
12621{
12622 return !iterator->dirp;
12623}
12624
Victor Stinner6036e442015-03-08 01:58:04 +010012625static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012626ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012627{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012628 DIR *dirp = iterator->dirp;
12629
12630 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012631 return;
12632
Victor Stinner6036e442015-03-08 01:58:04 +010012633 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012634 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012635#ifdef HAVE_FDOPENDIR
12636 if (iterator->path.fd != -1)
12637 rewinddir(dirp);
12638#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012639 closedir(dirp);
12640 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012641 return;
12642}
12643
12644static PyObject *
12645ScandirIterator_iternext(ScandirIterator *iterator)
12646{
12647 struct dirent *direntp;
12648 Py_ssize_t name_len;
12649 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012650 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012651
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012652 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012653 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012654 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012655
12656 while (1) {
12657 errno = 0;
12658 Py_BEGIN_ALLOW_THREADS
12659 direntp = readdir(iterator->dirp);
12660 Py_END_ALLOW_THREADS
12661
12662 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012663 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012664 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012665 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012666 break;
12667 }
12668
12669 /* Skip over . and .. */
12670 name_len = NAMLEN(direntp);
12671 is_dot = direntp->d_name[0] == '.' &&
12672 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12673 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012674 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012675 name_len, direntp->d_ino
12676#ifdef HAVE_DIRENT_D_TYPE
12677 , direntp->d_type
12678#endif
12679 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012680 if (!entry)
12681 break;
12682 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012683 }
12684
12685 /* Loop till we get a non-dot directory or finish iterating */
12686 }
12687
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012688 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012689 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012690 return NULL;
12691}
12692
12693#endif
12694
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012695static PyObject *
12696ScandirIterator_close(ScandirIterator *self, PyObject *args)
12697{
12698 ScandirIterator_closedir(self);
12699 Py_RETURN_NONE;
12700}
12701
12702static PyObject *
12703ScandirIterator_enter(PyObject *self, PyObject *args)
12704{
12705 Py_INCREF(self);
12706 return self;
12707}
12708
12709static PyObject *
12710ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12711{
12712 ScandirIterator_closedir(self);
12713 Py_RETURN_NONE;
12714}
12715
Victor Stinner6036e442015-03-08 01:58:04 +010012716static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012717ScandirIterator_finalize(ScandirIterator *iterator)
12718{
12719 PyObject *error_type, *error_value, *error_traceback;
12720
12721 /* Save the current exception, if any. */
12722 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12723
12724 if (!ScandirIterator_is_closed(iterator)) {
12725 ScandirIterator_closedir(iterator);
12726
12727 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12728 "unclosed scandir iterator %R", iterator)) {
12729 /* Spurious errors can appear at shutdown */
12730 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12731 PyErr_WriteUnraisable((PyObject *) iterator);
12732 }
12733 }
12734 }
12735
Victor Stinner7bfa4092016-03-23 00:43:54 +010012736 path_cleanup(&iterator->path);
12737
12738 /* Restore the saved exception. */
12739 PyErr_Restore(error_type, error_value, error_traceback);
12740}
12741
12742static void
Victor Stinner6036e442015-03-08 01:58:04 +010012743ScandirIterator_dealloc(ScandirIterator *iterator)
12744{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012745 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12746 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012747
Victor Stinner6036e442015-03-08 01:58:04 +010012748 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12749}
12750
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012751static PyMethodDef ScandirIterator_methods[] = {
12752 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12753 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12754 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12755 {NULL}
12756};
12757
Benjamin Peterson5646de42015-04-12 17:56:34 -040012758static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012759 PyVarObject_HEAD_INIT(NULL, 0)
12760 MODNAME ".ScandirIterator", /* tp_name */
12761 sizeof(ScandirIterator), /* tp_basicsize */
12762 0, /* tp_itemsize */
12763 /* methods */
12764 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12765 0, /* tp_print */
12766 0, /* tp_getattr */
12767 0, /* tp_setattr */
12768 0, /* tp_compare */
12769 0, /* tp_repr */
12770 0, /* tp_as_number */
12771 0, /* tp_as_sequence */
12772 0, /* tp_as_mapping */
12773 0, /* tp_hash */
12774 0, /* tp_call */
12775 0, /* tp_str */
12776 0, /* tp_getattro */
12777 0, /* tp_setattro */
12778 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012779 Py_TPFLAGS_DEFAULT
12780 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012781 0, /* tp_doc */
12782 0, /* tp_traverse */
12783 0, /* tp_clear */
12784 0, /* tp_richcompare */
12785 0, /* tp_weaklistoffset */
12786 PyObject_SelfIter, /* tp_iter */
12787 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012788 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012789 0, /* tp_members */
12790 0, /* tp_getset */
12791 0, /* tp_base */
12792 0, /* tp_dict */
12793 0, /* tp_descr_get */
12794 0, /* tp_descr_set */
12795 0, /* tp_dictoffset */
12796 0, /* tp_init */
12797 0, /* tp_alloc */
12798 0, /* tp_new */
12799 0, /* tp_free */
12800 0, /* tp_is_gc */
12801 0, /* tp_bases */
12802 0, /* tp_mro */
12803 0, /* tp_cache */
12804 0, /* tp_subclasses */
12805 0, /* tp_weaklist */
12806 0, /* tp_del */
12807 0, /* tp_version_tag */
12808 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012809};
12810
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012811/*[clinic input]
12812os.scandir
12813
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012814 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012815
12816Return an iterator of DirEntry objects for given path.
12817
BNMetricsb9427072018-11-02 15:20:19 +000012818path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012819is bytes, the names of yielded DirEntry objects will also be bytes; in
12820all other circumstances they will be str.
12821
12822If path is None, uses the path='.'.
12823[clinic start generated code]*/
12824
Victor Stinner6036e442015-03-08 01:58:04 +010012825static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012826os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012827/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012828{
12829 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012830#ifdef MS_WINDOWS
12831 wchar_t *path_strW;
12832#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012833 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012834#ifdef HAVE_FDOPENDIR
12835 int fd = -1;
12836#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012837#endif
12838
12839 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12840 if (!iterator)
12841 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012842
12843#ifdef MS_WINDOWS
12844 iterator->handle = INVALID_HANDLE_VALUE;
12845#else
12846 iterator->dirp = NULL;
12847#endif
12848
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012849 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012850 /* Move the ownership to iterator->path */
12851 path->object = NULL;
12852 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012853
12854#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012855 iterator->first_time = 1;
12856
12857 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12858 if (!path_strW)
12859 goto error;
12860
12861 Py_BEGIN_ALLOW_THREADS
12862 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12863 Py_END_ALLOW_THREADS
12864
12865 PyMem_Free(path_strW);
12866
12867 if (iterator->handle == INVALID_HANDLE_VALUE) {
12868 path_error(&iterator->path);
12869 goto error;
12870 }
12871#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012872 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012873#ifdef HAVE_FDOPENDIR
12874 if (path->fd != -1) {
12875 /* closedir() closes the FD, so we duplicate it */
12876 fd = _Py_dup(path->fd);
12877 if (fd == -1)
12878 goto error;
12879
12880 Py_BEGIN_ALLOW_THREADS
12881 iterator->dirp = fdopendir(fd);
12882 Py_END_ALLOW_THREADS
12883 }
12884 else
12885#endif
12886 {
12887 if (iterator->path.narrow)
12888 path_str = iterator->path.narrow;
12889 else
12890 path_str = ".";
12891
12892 Py_BEGIN_ALLOW_THREADS
12893 iterator->dirp = opendir(path_str);
12894 Py_END_ALLOW_THREADS
12895 }
Victor Stinner6036e442015-03-08 01:58:04 +010012896
12897 if (!iterator->dirp) {
12898 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012899#ifdef HAVE_FDOPENDIR
12900 if (fd != -1) {
12901 Py_BEGIN_ALLOW_THREADS
12902 close(fd);
12903 Py_END_ALLOW_THREADS
12904 }
12905#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012906 goto error;
12907 }
12908#endif
12909
12910 return (PyObject *)iterator;
12911
12912error:
12913 Py_DECREF(iterator);
12914 return NULL;
12915}
12916
Ethan Furman410ef8e2016-06-04 12:06:26 -070012917/*
12918 Return the file system path representation of the object.
12919
12920 If the object is str or bytes, then allow it to pass through with
12921 an incremented refcount. If the object defines __fspath__(), then
12922 return the result of that method. All other types raise a TypeError.
12923*/
12924PyObject *
12925PyOS_FSPath(PyObject *path)
12926{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012927 /* For error message reasons, this function is manually inlined in
12928 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012929 _Py_IDENTIFIER(__fspath__);
12930 PyObject *func = NULL;
12931 PyObject *path_repr = NULL;
12932
12933 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12934 Py_INCREF(path);
12935 return path;
12936 }
12937
12938 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12939 if (NULL == func) {
12940 return PyErr_Format(PyExc_TypeError,
12941 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012942 "not %.200s",
12943 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012944 }
12945
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012946 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012947 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012948 if (NULL == path_repr) {
12949 return NULL;
12950 }
12951
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012952 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12953 PyErr_Format(PyExc_TypeError,
12954 "expected %.200s.__fspath__() to return str or bytes, "
12955 "not %.200s", Py_TYPE(path)->tp_name,
12956 Py_TYPE(path_repr)->tp_name);
12957 Py_DECREF(path_repr);
12958 return NULL;
12959 }
12960
Ethan Furman410ef8e2016-06-04 12:06:26 -070012961 return path_repr;
12962}
12963
12964/*[clinic input]
12965os.fspath
12966
12967 path: object
12968
12969Return the file system path representation of the object.
12970
Brett Cannonb4f43e92016-06-09 14:32:08 -070012971If the object is str or bytes, then allow it to pass through as-is. If the
12972object defines __fspath__(), then return the result of that method. All other
12973types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012974[clinic start generated code]*/
12975
12976static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012977os_fspath_impl(PyObject *module, PyObject *path)
12978/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012979{
12980 return PyOS_FSPath(path);
12981}
Victor Stinner6036e442015-03-08 01:58:04 +010012982
Victor Stinner9b1f4742016-09-06 16:18:52 -070012983#ifdef HAVE_GETRANDOM_SYSCALL
12984/*[clinic input]
12985os.getrandom
12986
12987 size: Py_ssize_t
12988 flags: int=0
12989
12990Obtain a series of random bytes.
12991[clinic start generated code]*/
12992
12993static PyObject *
12994os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12995/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12996{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012997 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012998 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012999
13000 if (size < 0) {
13001 errno = EINVAL;
13002 return posix_error();
13003 }
13004
Victor Stinnerec2319c2016-09-20 23:00:59 +020013005 bytes = PyBytes_FromStringAndSize(NULL, size);
13006 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013007 PyErr_NoMemory();
13008 return NULL;
13009 }
13010
13011 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013012 n = syscall(SYS_getrandom,
13013 PyBytes_AS_STRING(bytes),
13014 PyBytes_GET_SIZE(bytes),
13015 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013016 if (n < 0 && errno == EINTR) {
13017 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013018 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013019 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013020
13021 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013022 continue;
13023 }
13024 break;
13025 }
13026
13027 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013028 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013029 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013030 }
13031
Victor Stinnerec2319c2016-09-20 23:00:59 +020013032 if (n != size) {
13033 _PyBytes_Resize(&bytes, n);
13034 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013035
13036 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013037
13038error:
13039 Py_DECREF(bytes);
13040 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013041}
13042#endif /* HAVE_GETRANDOM_SYSCALL */
13043
Larry Hastings31826802013-10-19 00:09:25 -070013044
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013045static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013046
13047 OS_STAT_METHODDEF
13048 OS_ACCESS_METHODDEF
13049 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013050 OS_CHDIR_METHODDEF
13051 OS_CHFLAGS_METHODDEF
13052 OS_CHMOD_METHODDEF
13053 OS_FCHMOD_METHODDEF
13054 OS_LCHMOD_METHODDEF
13055 OS_CHOWN_METHODDEF
13056 OS_FCHOWN_METHODDEF
13057 OS_LCHOWN_METHODDEF
13058 OS_LCHFLAGS_METHODDEF
13059 OS_CHROOT_METHODDEF
13060 OS_CTERMID_METHODDEF
13061 OS_GETCWD_METHODDEF
13062 OS_GETCWDB_METHODDEF
13063 OS_LINK_METHODDEF
13064 OS_LISTDIR_METHODDEF
13065 OS_LSTAT_METHODDEF
13066 OS_MKDIR_METHODDEF
13067 OS_NICE_METHODDEF
13068 OS_GETPRIORITY_METHODDEF
13069 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013070 OS_POSIX_SPAWN_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013071 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013072 OS_RENAME_METHODDEF
13073 OS_REPLACE_METHODDEF
13074 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013075 OS_SYMLINK_METHODDEF
13076 OS_SYSTEM_METHODDEF
13077 OS_UMASK_METHODDEF
13078 OS_UNAME_METHODDEF
13079 OS_UNLINK_METHODDEF
13080 OS_REMOVE_METHODDEF
13081 OS_UTIME_METHODDEF
13082 OS_TIMES_METHODDEF
13083 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013084 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013085 OS_EXECV_METHODDEF
13086 OS_EXECVE_METHODDEF
13087 OS_SPAWNV_METHODDEF
13088 OS_SPAWNVE_METHODDEF
13089 OS_FORK1_METHODDEF
13090 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013091 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013092 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13093 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13094 OS_SCHED_GETPARAM_METHODDEF
13095 OS_SCHED_GETSCHEDULER_METHODDEF
13096 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13097 OS_SCHED_SETPARAM_METHODDEF
13098 OS_SCHED_SETSCHEDULER_METHODDEF
13099 OS_SCHED_YIELD_METHODDEF
13100 OS_SCHED_SETAFFINITY_METHODDEF
13101 OS_SCHED_GETAFFINITY_METHODDEF
13102 OS_OPENPTY_METHODDEF
13103 OS_FORKPTY_METHODDEF
13104 OS_GETEGID_METHODDEF
13105 OS_GETEUID_METHODDEF
13106 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013107#ifdef HAVE_GETGROUPLIST
13108 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13109#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013110 OS_GETGROUPS_METHODDEF
13111 OS_GETPID_METHODDEF
13112 OS_GETPGRP_METHODDEF
13113 OS_GETPPID_METHODDEF
13114 OS_GETUID_METHODDEF
13115 OS_GETLOGIN_METHODDEF
13116 OS_KILL_METHODDEF
13117 OS_KILLPG_METHODDEF
13118 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013119#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013120 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013121#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013122 OS_SETUID_METHODDEF
13123 OS_SETEUID_METHODDEF
13124 OS_SETREUID_METHODDEF
13125 OS_SETGID_METHODDEF
13126 OS_SETEGID_METHODDEF
13127 OS_SETREGID_METHODDEF
13128 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013129#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013130 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013131#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013132 OS_GETPGID_METHODDEF
13133 OS_SETPGRP_METHODDEF
13134 OS_WAIT_METHODDEF
13135 OS_WAIT3_METHODDEF
13136 OS_WAIT4_METHODDEF
13137 OS_WAITID_METHODDEF
13138 OS_WAITPID_METHODDEF
13139 OS_GETSID_METHODDEF
13140 OS_SETSID_METHODDEF
13141 OS_SETPGID_METHODDEF
13142 OS_TCGETPGRP_METHODDEF
13143 OS_TCSETPGRP_METHODDEF
13144 OS_OPEN_METHODDEF
13145 OS_CLOSE_METHODDEF
13146 OS_CLOSERANGE_METHODDEF
13147 OS_DEVICE_ENCODING_METHODDEF
13148 OS_DUP_METHODDEF
13149 OS_DUP2_METHODDEF
13150 OS_LOCKF_METHODDEF
13151 OS_LSEEK_METHODDEF
13152 OS_READ_METHODDEF
13153 OS_READV_METHODDEF
13154 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013155 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013156 OS_WRITE_METHODDEF
13157 OS_WRITEV_METHODDEF
13158 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013159 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013160#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013161 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013162 posix_sendfile__doc__},
13163#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013164 OS_FSTAT_METHODDEF
13165 OS_ISATTY_METHODDEF
13166 OS_PIPE_METHODDEF
13167 OS_PIPE2_METHODDEF
13168 OS_MKFIFO_METHODDEF
13169 OS_MKNOD_METHODDEF
13170 OS_MAJOR_METHODDEF
13171 OS_MINOR_METHODDEF
13172 OS_MAKEDEV_METHODDEF
13173 OS_FTRUNCATE_METHODDEF
13174 OS_TRUNCATE_METHODDEF
13175 OS_POSIX_FALLOCATE_METHODDEF
13176 OS_POSIX_FADVISE_METHODDEF
13177 OS_PUTENV_METHODDEF
13178 OS_UNSETENV_METHODDEF
13179 OS_STRERROR_METHODDEF
13180 OS_FCHDIR_METHODDEF
13181 OS_FSYNC_METHODDEF
13182 OS_SYNC_METHODDEF
13183 OS_FDATASYNC_METHODDEF
13184 OS_WCOREDUMP_METHODDEF
13185 OS_WIFCONTINUED_METHODDEF
13186 OS_WIFSTOPPED_METHODDEF
13187 OS_WIFSIGNALED_METHODDEF
13188 OS_WIFEXITED_METHODDEF
13189 OS_WEXITSTATUS_METHODDEF
13190 OS_WTERMSIG_METHODDEF
13191 OS_WSTOPSIG_METHODDEF
13192 OS_FSTATVFS_METHODDEF
13193 OS_STATVFS_METHODDEF
13194 OS_CONFSTR_METHODDEF
13195 OS_SYSCONF_METHODDEF
13196 OS_FPATHCONF_METHODDEF
13197 OS_PATHCONF_METHODDEF
13198 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013199 OS__GETFULLPATHNAME_METHODDEF
13200 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013201 OS__GETDISKUSAGE_METHODDEF
13202 OS__GETFINALPATHNAME_METHODDEF
13203 OS__GETVOLUMEPATHNAME_METHODDEF
13204 OS_GETLOADAVG_METHODDEF
13205 OS_URANDOM_METHODDEF
13206 OS_SETRESUID_METHODDEF
13207 OS_SETRESGID_METHODDEF
13208 OS_GETRESUID_METHODDEF
13209 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013210
Larry Hastings2f936352014-08-05 14:04:04 +100013211 OS_GETXATTR_METHODDEF
13212 OS_SETXATTR_METHODDEF
13213 OS_REMOVEXATTR_METHODDEF
13214 OS_LISTXATTR_METHODDEF
13215
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013216#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13217 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13218#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013219 OS_CPU_COUNT_METHODDEF
13220 OS_GET_INHERITABLE_METHODDEF
13221 OS_SET_INHERITABLE_METHODDEF
13222 OS_GET_HANDLE_INHERITABLE_METHODDEF
13223 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013224#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013225 OS_GET_BLOCKING_METHODDEF
13226 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013227#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013228 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013229 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013230 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000013231 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013232};
13233
13234
Brian Curtin52173d42010-12-02 18:29:18 +000013235#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013236static int
Brian Curtin52173d42010-12-02 18:29:18 +000013237enable_symlink()
13238{
13239 HANDLE tok;
13240 TOKEN_PRIVILEGES tok_priv;
13241 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000013242
13243 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013244 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013245
13246 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013247 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013248
13249 tok_priv.PrivilegeCount = 1;
13250 tok_priv.Privileges[0].Luid = luid;
13251 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
13252
13253 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
13254 sizeof(TOKEN_PRIVILEGES),
13255 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013256 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013257
Brian Curtin3b4499c2010-12-28 14:31:47 +000013258 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
13259 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000013260}
13261#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
13262
Barry Warsaw4a342091996-12-19 23:50:02 +000013263static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013264all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013265{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013266#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013267 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013268#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013269#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013270 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013271#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013272#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013273 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013274#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013275#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013276 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013277#endif
Fred Drakec9680921999-12-13 16:37:25 +000013278#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013279 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013280#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013281#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013282 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013283#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013284#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013285 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013286#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013287#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013288 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013289#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013290#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013291 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013292#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013293#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013294 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013295#endif
13296#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013297 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013298#endif
13299#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013300 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013301#endif
13302#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013303 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013304#endif
13305#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013306 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013307#endif
13308#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013309 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013310#endif
13311#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013312 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013313#endif
13314#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013315 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013316#endif
13317#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013318 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013319#endif
13320#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013321 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013322#endif
13323#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013324 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013325#endif
13326#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013327 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013328#endif
13329#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013330 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013331#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013332#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013333 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013334#endif
13335#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013336 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013337#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013338#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013339 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013340#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013341#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013342 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013343#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013344#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013345#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013346 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013347#endif
13348#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013349 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013350#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013351#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013352#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013353 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013354#endif
13355#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013356 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013357#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013358#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013359 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013360#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013361#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013362 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013363#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013364#ifdef O_TMPFILE
13365 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13366#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013367#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013368 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013369#endif
13370#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013371 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013372#endif
13373#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013374 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013375#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013376#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013377 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013378#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013379#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013380 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013381#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013382
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013383
Jesus Cea94363612012-06-22 18:32:07 +020013384#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013385 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013386#endif
13387#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013388 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013389#endif
13390
Tim Peters5aa91602002-01-30 05:46:57 +000013391/* MS Windows */
13392#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013393 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013394 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013395#endif
13396#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013397 /* Optimize for short life (keep in memory). */
13398 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013399 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013400#endif
13401#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013402 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013403 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013404#endif
13405#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013406 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013407 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013408#endif
13409#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013410 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013411 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013412#endif
13413
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013414/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013415#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013416 /* Send a SIGIO signal whenever input or output
13417 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013418 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013419#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013420#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013421 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013422 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013423#endif
13424#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013425 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013426 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013427#endif
13428#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013429 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013430 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013431#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013432#ifdef O_NOLINKS
13433 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013434 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013435#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013436#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013437 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013438 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013439#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013440
Victor Stinner8c62be82010-05-06 00:08:46 +000013441 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013442#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013443 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013444#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013445#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013446 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013447#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013448#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013449 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013450#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013451#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013452 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013453#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013454#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013455 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013456#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013457#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013458 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013459#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013460#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013461 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013462#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013463#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013464 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013465#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013466#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013467 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013468#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013469#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013470 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013471#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013472#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013473 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013474#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013475#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013476 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013477#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013478#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013479 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013480#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013481#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013482 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013483#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013484#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013485 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013486#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013487#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013488 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013489#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013490#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013491 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013492#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013493
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013494 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013495#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013496 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013497#endif /* ST_RDONLY */
13498#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013499 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013500#endif /* ST_NOSUID */
13501
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013502 /* GNU extensions */
13503#ifdef ST_NODEV
13504 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13505#endif /* ST_NODEV */
13506#ifdef ST_NOEXEC
13507 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13508#endif /* ST_NOEXEC */
13509#ifdef ST_SYNCHRONOUS
13510 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13511#endif /* ST_SYNCHRONOUS */
13512#ifdef ST_MANDLOCK
13513 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13514#endif /* ST_MANDLOCK */
13515#ifdef ST_WRITE
13516 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13517#endif /* ST_WRITE */
13518#ifdef ST_APPEND
13519 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13520#endif /* ST_APPEND */
13521#ifdef ST_NOATIME
13522 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13523#endif /* ST_NOATIME */
13524#ifdef ST_NODIRATIME
13525 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13526#endif /* ST_NODIRATIME */
13527#ifdef ST_RELATIME
13528 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13529#endif /* ST_RELATIME */
13530
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013531 /* FreeBSD sendfile() constants */
13532#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013533 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013534#endif
13535#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013536 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013537#endif
13538#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013539 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013540#endif
13541
Ross Lagerwall7807c352011-03-17 20:20:30 +020013542 /* constants for posix_fadvise */
13543#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013544 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013545#endif
13546#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013547 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013548#endif
13549#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013550 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013551#endif
13552#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013553 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013554#endif
13555#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013556 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013557#endif
13558#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013559 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013560#endif
13561
13562 /* constants for waitid */
13563#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013564 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13565 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13566 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013567#endif
13568#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013569 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013570#endif
13571#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013572 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013573#endif
13574#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013575 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013576#endif
13577#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013578 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013579#endif
13580#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013581 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013582#endif
13583#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013584 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013585#endif
13586#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013587 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013588#endif
13589
13590 /* constants for lockf */
13591#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013592 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013593#endif
13594#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013595 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013596#endif
13597#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013598 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013599#endif
13600#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013601 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013602#endif
13603
Pablo Galindo4defba32018-01-27 16:16:37 +000013604#ifdef RWF_DSYNC
13605 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13606#endif
13607#ifdef RWF_HIPRI
13608 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13609#endif
13610#ifdef RWF_SYNC
13611 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13612#endif
13613#ifdef RWF_NOWAIT
13614 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13615#endif
13616
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013617/* constants for posix_spawn */
13618#ifdef HAVE_POSIX_SPAWN
13619 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13620 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13621 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13622#endif
13623
Guido van Rossum246bc171999-02-01 23:54:31 +000013624#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013625 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13626 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13627 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13628 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13629 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013630#endif
13631
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013632#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013633#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013634 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013635#endif
13636#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013637 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013638#endif
13639#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013640 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013641#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013642#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013643 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013644#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013645#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013646 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013647#endif
13648#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013649 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013650#endif
13651#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013652 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013653#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013654#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013655 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013656#endif
13657#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013658 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013659#endif
13660#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013661 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013662#endif
13663#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013664 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013665#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013666#endif
13667
Benjamin Peterson9428d532011-09-14 11:45:52 -040013668#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013669 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13670 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13671 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013672#endif
13673
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013674#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013675 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013676#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013677#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013678 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013679#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013680#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013681 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013682#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013683#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013684 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013685#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013686#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013687 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013688#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013689#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013690 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013691#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013692#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013693 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013694#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013695#if HAVE_DECL_RTLD_MEMBER
13696 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13697#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013698
Victor Stinner9b1f4742016-09-06 16:18:52 -070013699#ifdef HAVE_GETRANDOM_SYSCALL
13700 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13701 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13702#endif
13703
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013704#if defined(__APPLE__)
13705 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13706#endif
13707
Victor Stinner8c62be82010-05-06 00:08:46 +000013708 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013709}
13710
13711
Martin v. Löwis1a214512008-06-11 05:26:20 +000013712static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013713 PyModuleDef_HEAD_INIT,
13714 MODNAME,
13715 posix__doc__,
13716 -1,
13717 posix_methods,
13718 NULL,
13719 NULL,
13720 NULL,
13721 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013722};
13723
13724
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013725static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013726
13727#ifdef HAVE_FACCESSAT
13728 "HAVE_FACCESSAT",
13729#endif
13730
13731#ifdef HAVE_FCHDIR
13732 "HAVE_FCHDIR",
13733#endif
13734
13735#ifdef HAVE_FCHMOD
13736 "HAVE_FCHMOD",
13737#endif
13738
13739#ifdef HAVE_FCHMODAT
13740 "HAVE_FCHMODAT",
13741#endif
13742
13743#ifdef HAVE_FCHOWN
13744 "HAVE_FCHOWN",
13745#endif
13746
Larry Hastings00964ed2013-08-12 13:49:30 -040013747#ifdef HAVE_FCHOWNAT
13748 "HAVE_FCHOWNAT",
13749#endif
13750
Larry Hastings9cf065c2012-06-22 16:30:09 -070013751#ifdef HAVE_FEXECVE
13752 "HAVE_FEXECVE",
13753#endif
13754
13755#ifdef HAVE_FDOPENDIR
13756 "HAVE_FDOPENDIR",
13757#endif
13758
Georg Brandl306336b2012-06-24 12:55:33 +020013759#ifdef HAVE_FPATHCONF
13760 "HAVE_FPATHCONF",
13761#endif
13762
Larry Hastings9cf065c2012-06-22 16:30:09 -070013763#ifdef HAVE_FSTATAT
13764 "HAVE_FSTATAT",
13765#endif
13766
13767#ifdef HAVE_FSTATVFS
13768 "HAVE_FSTATVFS",
13769#endif
13770
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013771#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013772 "HAVE_FTRUNCATE",
13773#endif
13774
Larry Hastings9cf065c2012-06-22 16:30:09 -070013775#ifdef HAVE_FUTIMENS
13776 "HAVE_FUTIMENS",
13777#endif
13778
13779#ifdef HAVE_FUTIMES
13780 "HAVE_FUTIMES",
13781#endif
13782
13783#ifdef HAVE_FUTIMESAT
13784 "HAVE_FUTIMESAT",
13785#endif
13786
13787#ifdef HAVE_LINKAT
13788 "HAVE_LINKAT",
13789#endif
13790
13791#ifdef HAVE_LCHFLAGS
13792 "HAVE_LCHFLAGS",
13793#endif
13794
13795#ifdef HAVE_LCHMOD
13796 "HAVE_LCHMOD",
13797#endif
13798
13799#ifdef HAVE_LCHOWN
13800 "HAVE_LCHOWN",
13801#endif
13802
13803#ifdef HAVE_LSTAT
13804 "HAVE_LSTAT",
13805#endif
13806
13807#ifdef HAVE_LUTIMES
13808 "HAVE_LUTIMES",
13809#endif
13810
13811#ifdef HAVE_MKDIRAT
13812 "HAVE_MKDIRAT",
13813#endif
13814
13815#ifdef HAVE_MKFIFOAT
13816 "HAVE_MKFIFOAT",
13817#endif
13818
13819#ifdef HAVE_MKNODAT
13820 "HAVE_MKNODAT",
13821#endif
13822
13823#ifdef HAVE_OPENAT
13824 "HAVE_OPENAT",
13825#endif
13826
13827#ifdef HAVE_READLINKAT
13828 "HAVE_READLINKAT",
13829#endif
13830
13831#ifdef HAVE_RENAMEAT
13832 "HAVE_RENAMEAT",
13833#endif
13834
13835#ifdef HAVE_SYMLINKAT
13836 "HAVE_SYMLINKAT",
13837#endif
13838
13839#ifdef HAVE_UNLINKAT
13840 "HAVE_UNLINKAT",
13841#endif
13842
13843#ifdef HAVE_UTIMENSAT
13844 "HAVE_UTIMENSAT",
13845#endif
13846
13847#ifdef MS_WINDOWS
13848 "MS_WINDOWS",
13849#endif
13850
13851 NULL
13852};
13853
13854
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013855PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013856INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013857{
Victor Stinner8c62be82010-05-06 00:08:46 +000013858 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013859 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013860 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013861
Brian Curtin52173d42010-12-02 18:29:18 +000013862#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013863 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013864#endif
13865
Victor Stinner8c62be82010-05-06 00:08:46 +000013866 m = PyModule_Create(&posixmodule);
13867 if (m == NULL)
13868 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013869
Victor Stinner8c62be82010-05-06 00:08:46 +000013870 /* Initialize environ dictionary */
13871 v = convertenviron();
13872 Py_XINCREF(v);
13873 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13874 return NULL;
13875 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013876
Victor Stinner8c62be82010-05-06 00:08:46 +000013877 if (all_ins(m))
13878 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013879
Victor Stinner8c62be82010-05-06 00:08:46 +000013880 if (setup_confname_tables(m))
13881 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013882
Victor Stinner8c62be82010-05-06 00:08:46 +000013883 Py_INCREF(PyExc_OSError);
13884 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013885
Guido van Rossumb3d39562000-01-31 18:41:26 +000013886#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013887 if (posix_putenv_garbage == NULL)
13888 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013889#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013890
Victor Stinner8c62be82010-05-06 00:08:46 +000013891 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013892#if defined(HAVE_WAITID) && !defined(__APPLE__)
13893 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013894 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
13895 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013896 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013897 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013898#endif
13899
Christian Heimes25827622013-10-12 01:27:08 +020013900 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013901 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13902 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13903 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013904 StatResultType = PyStructSequence_NewType(&stat_result_desc);
13905 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013906 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013907 }
13908 structseq_new = StatResultType->tp_new;
13909 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013910
Christian Heimes25827622013-10-12 01:27:08 +020013911 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013912 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
13913 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013914 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013915 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013916#ifdef NEED_TICKS_PER_SECOND
13917# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013918 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013919# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013920 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013921# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013922 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013923# endif
13924#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013925
William Orr81574b82018-10-01 22:19:56 -070013926#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013927 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013928 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
13929 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013930 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013931 }
13932 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013933#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013934
13935 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013936 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
13937 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013938 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013939 }
Victor Stinner6036e442015-03-08 01:58:04 +010013940
13941 /* initialize scandir types */
13942 if (PyType_Ready(&ScandirIteratorType) < 0)
13943 return NULL;
13944 if (PyType_Ready(&DirEntryType) < 0)
13945 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013946 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013947#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013948 Py_INCREF((PyObject*) WaitidResultType);
13949 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020013950#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013951 Py_INCREF((PyObject*) StatResultType);
13952 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
13953 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000013954 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013955 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013956
13957#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013958 Py_INCREF(SchedParamType);
13959 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013960#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013961
Larry Hastings605a62d2012-06-24 04:33:36 -070013962 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013963 TimesResultType = PyStructSequence_NewType(&times_result_desc);
13964 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013965 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013966 }
13967 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070013968
13969 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013970 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
13971 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013972 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013973 }
13974 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070013975
Thomas Wouters477c8d52006-05-27 19:21:47 +000013976#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013977 /*
13978 * Step 2 of weak-linking support on Mac OS X.
13979 *
13980 * The code below removes functions that are not available on the
13981 * currently active platform.
13982 *
13983 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013984 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013985 * OSX 10.4.
13986 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013987#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013988 if (fstatvfs == NULL) {
13989 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13990 return NULL;
13991 }
13992 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013993#endif /* HAVE_FSTATVFS */
13994
13995#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013996 if (statvfs == NULL) {
13997 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13998 return NULL;
13999 }
14000 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014001#endif /* HAVE_STATVFS */
14002
14003# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014004 if (lchown == NULL) {
14005 if (PyObject_DelAttrString(m, "lchown") == -1) {
14006 return NULL;
14007 }
14008 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014009#endif /* HAVE_LCHOWN */
14010
14011
14012#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014013
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014014 Py_INCREF(TerminalSizeType);
14015 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014016
Larry Hastings6fe20b32012-04-19 15:07:49 -070014017 billion = PyLong_FromLong(1000000000);
14018 if (!billion)
14019 return NULL;
14020
Larry Hastings9cf065c2012-06-22 16:30:09 -070014021 /* suppress "function not used" warnings */
14022 {
14023 int ignored;
14024 fd_specified("", -1);
14025 follow_symlinks_specified("", 1);
14026 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14027 dir_fd_converter(Py_None, &ignored);
14028 dir_fd_unavailable(Py_None, &ignored);
14029 }
14030
14031 /*
14032 * provide list of locally available functions
14033 * so os.py can populate support_* lists
14034 */
14035 list = PyList_New(0);
14036 if (!list)
14037 return NULL;
14038 for (trace = have_functions; *trace; trace++) {
14039 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14040 if (!unicode)
14041 return NULL;
14042 if (PyList_Append(list, unicode))
14043 return NULL;
14044 Py_DECREF(unicode);
14045 }
14046 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014047
14048 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014049 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014050
14051 initialized = 1;
14052
Victor Stinner8c62be82010-05-06 00:08:46 +000014053 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014054}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014055
14056#ifdef __cplusplus
14057}
14058#endif