blob: bd97f0abe1b977bb291a840b9717f3caaff2b4eb [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"");
1359 if (_wenviron == NULL)
1360 return d;
1361 /* This part ignores errors */
1362 for (e = _wenviron; *e != NULL; e++) {
1363 PyObject *k;
1364 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001365 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 if (p == NULL)
1367 continue;
1368 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1369 if (k == NULL) {
1370 PyErr_Clear();
1371 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001372 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001373 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1374 if (v == NULL) {
1375 PyErr_Clear();
1376 Py_DECREF(k);
1377 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001378 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 if (PyDict_GetItem(d, k) == NULL) {
1380 if (PyDict_SetItem(d, k, v) != 0)
1381 PyErr_Clear();
1382 }
1383 Py_DECREF(k);
1384 Py_DECREF(v);
1385 }
1386#else
1387 if (environ == NULL)
1388 return d;
1389 /* This part ignores errors */
1390 for (e = environ; *e != NULL; e++) {
1391 PyObject *k;
1392 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001393 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 if (p == NULL)
1395 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001396 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001397 if (k == NULL) {
1398 PyErr_Clear();
1399 continue;
1400 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001401 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 if (v == NULL) {
1403 PyErr_Clear();
1404 Py_DECREF(k);
1405 continue;
1406 }
1407 if (PyDict_GetItem(d, k) == NULL) {
1408 if (PyDict_SetItem(d, k, v) != 0)
1409 PyErr_Clear();
1410 }
1411 Py_DECREF(k);
1412 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001413 }
1414#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001415 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001416}
1417
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001418/* Set a POSIX-specific error from errno, and return NULL */
1419
Barry Warsawd58d7641998-07-23 16:14:40 +00001420static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001421posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001422{
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001424}
Mark Hammondef8b6542001-05-13 08:04:26 +00001425
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001426#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001427static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001428win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001429{
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 /* XXX We should pass the function name along in the future.
1431 (winreg.c also wants to pass the function name.)
1432 This would however require an additional param to the
1433 Windows error object, which is non-trivial.
1434 */
1435 errno = GetLastError();
1436 if (filename)
1437 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1438 else
1439 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001440}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001441
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001442static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001443win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001444{
1445 /* XXX - see win32_error for comments on 'function' */
1446 errno = GetLastError();
1447 if (filename)
1448 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001449 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001450 errno,
1451 filename);
1452 else
1453 return PyErr_SetFromWindowsErr(errno);
1454}
1455
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001456#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001457
Larry Hastings9cf065c2012-06-22 16:30:09 -07001458static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001459posix_path_object_error(PyObject *path)
1460{
1461 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1462}
1463
1464static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001465path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001466{
1467#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001468 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1469 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001470#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001471 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001472#endif
1473}
1474
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001475static PyObject *
1476path_object_error2(PyObject *path, PyObject *path2)
1477{
1478#ifdef MS_WINDOWS
1479 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1480 PyExc_OSError, 0, path, path2);
1481#else
1482 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1483#endif
1484}
1485
1486static PyObject *
1487path_error(path_t *path)
1488{
1489 return path_object_error(path->object);
1490}
Larry Hastings31826802013-10-19 00:09:25 -07001491
Larry Hastingsb0827312014-02-09 22:05:19 -08001492static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001493posix_path_error(path_t *path)
1494{
1495 return posix_path_object_error(path->object);
1496}
1497
1498static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001499path_error2(path_t *path, path_t *path2)
1500{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001501 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001502}
1503
1504
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001505/* POSIX generic methods */
1506
Larry Hastings2f936352014-08-05 14:04:04 +10001507static int
1508fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001509{
Victor Stinner8c62be82010-05-06 00:08:46 +00001510 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001511 int *pointer = (int *)p;
1512 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001514 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001515 *pointer = fd;
1516 return 1;
1517}
1518
1519static PyObject *
1520posix_fildes_fd(int fd, int (*func)(int))
1521{
1522 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001523 int async_err = 0;
1524
1525 do {
1526 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001527 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001528 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001529 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001530 Py_END_ALLOW_THREADS
1531 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1532 if (res != 0)
1533 return (!async_err) ? posix_error() : NULL;
1534 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001535}
Guido van Rossum21142a01999-01-08 21:05:37 +00001536
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001537
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001538#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539/* This is a reimplementation of the C library's chdir function,
1540 but one that produces Win32 errors instead of DOS error codes.
1541 chdir is essentially a wrapper around SetCurrentDirectory; however,
1542 it also needs to set "magic" environment variables indicating
1543 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001544static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001545win32_wchdir(LPCWSTR path)
1546{
Victor Stinnered537822015-12-13 21:40:26 +01001547 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001548 int result;
1549 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550
Victor Stinner8c62be82010-05-06 00:08:46 +00001551 if(!SetCurrentDirectoryW(path))
1552 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001553 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 if (!result)
1555 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001556 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001557 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 if (!new_path) {
1559 SetLastError(ERROR_OUTOFMEMORY);
1560 return FALSE;
1561 }
1562 result = GetCurrentDirectoryW(result, new_path);
1563 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001564 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 return FALSE;
1566 }
1567 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001568 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1569 wcsncmp(new_path, L"//", 2) == 0);
1570 if (!is_unc_like_path) {
1571 env[1] = new_path[0];
1572 result = SetEnvironmentVariableW(env, new_path);
1573 }
Victor Stinnered537822015-12-13 21:40:26 +01001574 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001575 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001576 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001577}
1578#endif
1579
Martin v. Löwis14694662006-02-03 12:54:16 +00001580#ifdef MS_WINDOWS
1581/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1582 - time stamps are restricted to second resolution
1583 - file modification times suffer from forth-and-back conversions between
1584 UTC and local time
1585 Therefore, we implement our own stat, based on the Win32 API directly.
1586*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001587#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001588#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001589
Victor Stinner6036e442015-03-08 01:58:04 +01001590static void
Steve Dowercc16be82016-09-08 10:35:16 -07001591find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1592 BY_HANDLE_FILE_INFORMATION *info,
1593 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001594{
1595 memset(info, 0, sizeof(*info));
1596 info->dwFileAttributes = pFileData->dwFileAttributes;
1597 info->ftCreationTime = pFileData->ftCreationTime;
1598 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1599 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1600 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1601 info->nFileSizeLow = pFileData->nFileSizeLow;
1602/* info->nNumberOfLinks = 1; */
1603 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1604 *reparse_tag = pFileData->dwReserved0;
1605 else
1606 *reparse_tag = 0;
1607}
1608
Guido van Rossumd8faa362007-04-27 19:54:29 +00001609static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001610attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001611{
Victor Stinner8c62be82010-05-06 00:08:46 +00001612 HANDLE hFindFile;
1613 WIN32_FIND_DATAW FileData;
1614 hFindFile = FindFirstFileW(pszFile, &FileData);
1615 if (hFindFile == INVALID_HANDLE_VALUE)
1616 return FALSE;
1617 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001618 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001620}
1621
Brian Curtind25aef52011-06-13 15:16:04 -05001622static BOOL
1623get_target_path(HANDLE hdl, wchar_t **target_path)
1624{
1625 int buf_size, result_length;
1626 wchar_t *buf;
1627
1628 /* We have a good handle to the target, use it to determine
1629 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001630 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1631 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if(!buf_size)
1633 return FALSE;
1634
Victor Stinnerc36674a2016-03-16 14:30:16 +01001635 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001636 if (!buf) {
1637 SetLastError(ERROR_OUTOFMEMORY);
1638 return FALSE;
1639 }
1640
Steve Dower2ea51c92015-03-20 21:49:12 -07001641 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001642 buf, buf_size, VOLUME_NAME_DOS);
1643
1644 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001645 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001646 return FALSE;
1647 }
1648
1649 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001650 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001651 return FALSE;
1652 }
1653
1654 buf[result_length] = 0;
1655
1656 *target_path = buf;
1657 return TRUE;
1658}
1659
1660static int
Steve Dowercc16be82016-09-08 10:35:16 -07001661win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001662 BOOL traverse)
1663{
Victor Stinner26de69d2011-06-17 15:15:38 +02001664 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001665 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001666 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001667 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001668 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001669 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670
Steve Dowercc16be82016-09-08 10:35:16 -07001671 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001673 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001674 0, /* share mode */
1675 NULL, /* security attributes */
1676 OPEN_EXISTING,
1677 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001678 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1679 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001680 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001681 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1682 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683 NULL);
1684
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001686 /* Either the target doesn't exist, or we don't have access to
1687 get a handle to it. If the former, we need to return an error.
1688 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001689 DWORD lastError = GetLastError();
1690 if (lastError != ERROR_ACCESS_DENIED &&
1691 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 return -1;
1693 /* Could not get attributes on open file. Fall back to
1694 reading the directory. */
1695 if (!attributes_from_dir(path, &info, &reparse_tag))
1696 /* Very strange. This should not fail now */
1697 return -1;
1698 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1699 if (traverse) {
1700 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001701 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001702 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001703 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001705 } else {
1706 if (!GetFileInformationByHandle(hFile, &info)) {
1707 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001708 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 }
1710 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001711 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1712 return -1;
1713
1714 /* Close the outer open file handle now that we're about to
1715 reopen it with different flags. */
1716 if (!CloseHandle(hFile))
1717 return -1;
1718
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001720 /* In order to call GetFinalPathNameByHandle we need to open
1721 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001722 hFile2 = CreateFileW(
1723 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1724 NULL, OPEN_EXISTING,
1725 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1726 NULL);
1727 if (hFile2 == INVALID_HANDLE_VALUE)
1728 return -1;
1729
1730 if (!get_target_path(hFile2, &target_path))
1731 return -1;
1732
Steve Dowercc16be82016-09-08 10:35:16 -07001733 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001734 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001735 return code;
1736 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001737 } else
1738 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001739 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001740 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001741
1742 /* Set S_IEXEC if it is an .exe, .bat, ... */
1743 dot = wcsrchr(path, '.');
1744 if (dot) {
1745 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1746 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1747 result->st_mode |= 0111;
1748 }
1749 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001750}
1751
1752static int
Steve Dowercc16be82016-09-08 10:35:16 -07001753win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001754{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001755 /* Protocol violation: we explicitly clear errno, instead of
1756 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001757 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758 errno = 0;
1759 return code;
1760}
Brian Curtind25aef52011-06-13 15:16:04 -05001761/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001762
1763 In Posix, stat automatically traverses symlinks and returns the stat
1764 structure for the target. In Windows, the equivalent GetFileAttributes by
1765 default does not traverse symlinks and instead returns attributes for
1766 the symlink.
1767
1768 Therefore, win32_lstat will get the attributes traditionally, and
1769 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001770 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001771
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001772static int
Steve Dowercc16be82016-09-08 10:35:16 -07001773win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001774{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001776}
1777
Victor Stinner8c62be82010-05-06 00:08:46 +00001778static int
Steve Dowercc16be82016-09-08 10:35:16 -07001779win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001780{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001781 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001782}
1783
Martin v. Löwis14694662006-02-03 12:54:16 +00001784#endif /* MS_WINDOWS */
1785
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001786PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001787"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001788This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001789 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001790or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1791\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001792Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1793or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001794\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001795See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001796
1797static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001798 {"st_mode", "protection bits"},
1799 {"st_ino", "inode"},
1800 {"st_dev", "device"},
1801 {"st_nlink", "number of hard links"},
1802 {"st_uid", "user ID of owner"},
1803 {"st_gid", "group ID of owner"},
1804 {"st_size", "total size, in bytes"},
1805 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1806 {NULL, "integer time of last access"},
1807 {NULL, "integer time of last modification"},
1808 {NULL, "integer time of last change"},
1809 {"st_atime", "time of last access"},
1810 {"st_mtime", "time of last modification"},
1811 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001812 {"st_atime_ns", "time of last access in nanoseconds"},
1813 {"st_mtime_ns", "time of last modification in nanoseconds"},
1814 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001815#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001816 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001817#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001818#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001820#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001821#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001822 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001823#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001824#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001825 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001826#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001827#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001829#endif
1830#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001832#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001833#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1834 {"st_file_attributes", "Windows file attribute bits"},
1835#endif
jcea6c51d512018-01-28 14:00:08 +01001836#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1837 {"st_fstype", "Type of filesystem"},
1838#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001840};
1841
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001842#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001843#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001844#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001845#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001846#endif
1847
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001848#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1850#else
1851#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1852#endif
1853
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001854#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001855#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1856#else
1857#define ST_RDEV_IDX ST_BLOCKS_IDX
1858#endif
1859
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001860#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1861#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1862#else
1863#define ST_FLAGS_IDX ST_RDEV_IDX
1864#endif
1865
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001866#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001867#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001868#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001869#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001870#endif
1871
1872#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1873#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1874#else
1875#define ST_BIRTHTIME_IDX ST_GEN_IDX
1876#endif
1877
Zachary Ware63f277b2014-06-19 09:46:37 -05001878#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1879#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1880#else
1881#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1882#endif
1883
jcea6c51d512018-01-28 14:00:08 +01001884#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1885#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1886#else
1887#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1888#endif
1889
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001890static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001891 "stat_result", /* name */
1892 stat_result__doc__, /* doc */
1893 stat_result_fields,
1894 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001895};
1896
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001898"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1899This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001900 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001901or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001902\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001903See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001904
1905static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 {"f_bsize", },
1907 {"f_frsize", },
1908 {"f_blocks", },
1909 {"f_bfree", },
1910 {"f_bavail", },
1911 {"f_files", },
1912 {"f_ffree", },
1913 {"f_favail", },
1914 {"f_flag", },
1915 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001916 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001918};
1919
1920static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 "statvfs_result", /* name */
1922 statvfs_result__doc__, /* doc */
1923 statvfs_result_fields,
1924 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001925};
1926
Ross Lagerwall7807c352011-03-17 20:20:30 +02001927#if defined(HAVE_WAITID) && !defined(__APPLE__)
1928PyDoc_STRVAR(waitid_result__doc__,
1929"waitid_result: Result from waitid.\n\n\
1930This object may be accessed either as a tuple of\n\
1931 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1932or via the attributes si_pid, si_uid, and so on.\n\
1933\n\
1934See os.waitid for more information.");
1935
1936static PyStructSequence_Field waitid_result_fields[] = {
1937 {"si_pid", },
1938 {"si_uid", },
1939 {"si_signo", },
1940 {"si_status", },
1941 {"si_code", },
1942 {0}
1943};
1944
1945static PyStructSequence_Desc waitid_result_desc = {
1946 "waitid_result", /* name */
1947 waitid_result__doc__, /* doc */
1948 waitid_result_fields,
1949 5
1950};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001951static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02001952#endif
1953
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001954static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001955static PyTypeObject* StatResultType;
1956static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07001957#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001958static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001959#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001960static newfunc structseq_new;
1961
1962static PyObject *
1963statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1964{
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 PyStructSequence *result;
1966 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001967
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 result = (PyStructSequence*)structseq_new(type, args, kwds);
1969 if (!result)
1970 return NULL;
1971 /* If we have been initialized from a tuple,
1972 st_?time might be set to None. Initialize it
1973 from the int slots. */
1974 for (i = 7; i <= 9; i++) {
1975 if (result->ob_item[i+3] == Py_None) {
1976 Py_DECREF(Py_None);
1977 Py_INCREF(result->ob_item[i]);
1978 result->ob_item[i+3] = result->ob_item[i];
1979 }
1980 }
1981 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001982}
1983
1984
Larry Hastings6fe20b32012-04-19 15:07:49 -07001985static PyObject *billion = NULL;
1986
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001987static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001988fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001989{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001990 PyObject *s = _PyLong_FromTime_t(sec);
1991 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1992 PyObject *s_in_ns = NULL;
1993 PyObject *ns_total = NULL;
1994 PyObject *float_s = NULL;
1995
1996 if (!(s && ns_fractional))
1997 goto exit;
1998
1999 s_in_ns = PyNumber_Multiply(s, billion);
2000 if (!s_in_ns)
2001 goto exit;
2002
2003 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2004 if (!ns_total)
2005 goto exit;
2006
Victor Stinner01b5aab2017-10-24 02:02:00 -07002007 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2008 if (!float_s) {
2009 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002010 }
2011
2012 PyStructSequence_SET_ITEM(v, index, s);
2013 PyStructSequence_SET_ITEM(v, index+3, float_s);
2014 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2015 s = NULL;
2016 float_s = NULL;
2017 ns_total = NULL;
2018exit:
2019 Py_XDECREF(s);
2020 Py_XDECREF(ns_fractional);
2021 Py_XDECREF(s_in_ns);
2022 Py_XDECREF(ns_total);
2023 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002024}
2025
Tim Peters5aa91602002-01-30 05:46:57 +00002026/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002027 (used by posix_stat() and posix_fstat()) */
2028static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002029_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002030{
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002032 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 if (v == NULL)
2034 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002035
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002037 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002038 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002039#ifdef MS_WINDOWS
2040 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002041#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002042 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002043#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002045#if defined(MS_WINDOWS)
2046 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2047 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2048#else
2049 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2050 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2051#endif
xdegaye50e86032017-05-22 11:15:08 +02002052 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2053 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002054
Martin v. Löwis14694662006-02-03 12:54:16 +00002055#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 ansec = st->st_atim.tv_nsec;
2057 mnsec = st->st_mtim.tv_nsec;
2058 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002059#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 ansec = st->st_atimespec.tv_nsec;
2061 mnsec = st->st_mtimespec.tv_nsec;
2062 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002063#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 ansec = st->st_atime_nsec;
2065 mnsec = st->st_mtime_nsec;
2066 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002067#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002068 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002069#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002070 fill_time(v, 7, st->st_atime, ansec);
2071 fill_time(v, 8, st->st_mtime, mnsec);
2072 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002073
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002074#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2076 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002077#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002078#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002079 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2080 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002081#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002082#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2084 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002085#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002086#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2088 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002089#endif
2090#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002092 PyObject *val;
2093 unsigned long bsec,bnsec;
2094 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002095#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002096 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002097#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002098 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002099#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002100 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002101 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2102 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002104#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002105#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002106 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2107 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002108#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002109#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2110 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2111 PyLong_FromUnsignedLong(st->st_file_attributes));
2112#endif
jcea6c51d512018-01-28 14:00:08 +01002113#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2114 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2115 PyUnicode_FromString(st->st_fstype));
2116#endif
Fred Drake699f3522000-06-29 21:12:41 +00002117
Victor Stinner8c62be82010-05-06 00:08:46 +00002118 if (PyErr_Occurred()) {
2119 Py_DECREF(v);
2120 return NULL;
2121 }
Fred Drake699f3522000-06-29 21:12:41 +00002122
Victor Stinner8c62be82010-05-06 00:08:46 +00002123 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002124}
2125
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002126/* POSIX methods */
2127
Guido van Rossum94f6f721999-01-06 18:42:14 +00002128
2129static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002130posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002131 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002132{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002133 STRUCT_STAT st;
2134 int result;
2135
2136#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2137 if (follow_symlinks_specified(function_name, follow_symlinks))
2138 return NULL;
2139#endif
2140
2141 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2142 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2143 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2144 return NULL;
2145
2146 Py_BEGIN_ALLOW_THREADS
2147 if (path->fd != -1)
2148 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002149#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002150 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002151 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002152 else
Steve Dowercc16be82016-09-08 10:35:16 -07002153 result = win32_lstat(path->wide, &st);
2154#else
2155 else
2156#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002157 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2158 result = LSTAT(path->narrow, &st);
2159 else
Steve Dowercc16be82016-09-08 10:35:16 -07002160#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002161#ifdef HAVE_FSTATAT
2162 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2163 result = fstatat(dir_fd, path->narrow, &st,
2164 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2165 else
Steve Dowercc16be82016-09-08 10:35:16 -07002166#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002167 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002168#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002169 Py_END_ALLOW_THREADS
2170
Victor Stinner292c8352012-10-30 02:17:38 +01002171 if (result != 0) {
2172 return path_error(path);
2173 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002174
2175 return _pystat_fromstructstat(&st);
2176}
2177
Larry Hastings2f936352014-08-05 14:04:04 +10002178/*[python input]
2179
2180for s in """
2181
2182FACCESSAT
2183FCHMODAT
2184FCHOWNAT
2185FSTATAT
2186LINKAT
2187MKDIRAT
2188MKFIFOAT
2189MKNODAT
2190OPENAT
2191READLINKAT
2192SYMLINKAT
2193UNLINKAT
2194
2195""".strip().split():
2196 s = s.strip()
2197 print("""
2198#ifdef HAVE_{s}
2199 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002200#else
Larry Hastings2f936352014-08-05 14:04:04 +10002201 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002202#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002203""".rstrip().format(s=s))
2204
2205for s in """
2206
2207FCHDIR
2208FCHMOD
2209FCHOWN
2210FDOPENDIR
2211FEXECVE
2212FPATHCONF
2213FSTATVFS
2214FTRUNCATE
2215
2216""".strip().split():
2217 s = s.strip()
2218 print("""
2219#ifdef HAVE_{s}
2220 #define PATH_HAVE_{s} 1
2221#else
2222 #define PATH_HAVE_{s} 0
2223#endif
2224
2225""".rstrip().format(s=s))
2226[python start generated code]*/
2227
2228#ifdef HAVE_FACCESSAT
2229 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2230#else
2231 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2232#endif
2233
2234#ifdef HAVE_FCHMODAT
2235 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2236#else
2237 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2238#endif
2239
2240#ifdef HAVE_FCHOWNAT
2241 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2242#else
2243 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2244#endif
2245
2246#ifdef HAVE_FSTATAT
2247 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2248#else
2249 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2250#endif
2251
2252#ifdef HAVE_LINKAT
2253 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2254#else
2255 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2256#endif
2257
2258#ifdef HAVE_MKDIRAT
2259 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2260#else
2261 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2262#endif
2263
2264#ifdef HAVE_MKFIFOAT
2265 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2266#else
2267 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2268#endif
2269
2270#ifdef HAVE_MKNODAT
2271 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2272#else
2273 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2274#endif
2275
2276#ifdef HAVE_OPENAT
2277 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2278#else
2279 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2280#endif
2281
2282#ifdef HAVE_READLINKAT
2283 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2284#else
2285 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2286#endif
2287
2288#ifdef HAVE_SYMLINKAT
2289 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2290#else
2291 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2292#endif
2293
2294#ifdef HAVE_UNLINKAT
2295 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2296#else
2297 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2298#endif
2299
2300#ifdef HAVE_FCHDIR
2301 #define PATH_HAVE_FCHDIR 1
2302#else
2303 #define PATH_HAVE_FCHDIR 0
2304#endif
2305
2306#ifdef HAVE_FCHMOD
2307 #define PATH_HAVE_FCHMOD 1
2308#else
2309 #define PATH_HAVE_FCHMOD 0
2310#endif
2311
2312#ifdef HAVE_FCHOWN
2313 #define PATH_HAVE_FCHOWN 1
2314#else
2315 #define PATH_HAVE_FCHOWN 0
2316#endif
2317
2318#ifdef HAVE_FDOPENDIR
2319 #define PATH_HAVE_FDOPENDIR 1
2320#else
2321 #define PATH_HAVE_FDOPENDIR 0
2322#endif
2323
2324#ifdef HAVE_FEXECVE
2325 #define PATH_HAVE_FEXECVE 1
2326#else
2327 #define PATH_HAVE_FEXECVE 0
2328#endif
2329
2330#ifdef HAVE_FPATHCONF
2331 #define PATH_HAVE_FPATHCONF 1
2332#else
2333 #define PATH_HAVE_FPATHCONF 0
2334#endif
2335
2336#ifdef HAVE_FSTATVFS
2337 #define PATH_HAVE_FSTATVFS 1
2338#else
2339 #define PATH_HAVE_FSTATVFS 0
2340#endif
2341
2342#ifdef HAVE_FTRUNCATE
2343 #define PATH_HAVE_FTRUNCATE 1
2344#else
2345 #define PATH_HAVE_FTRUNCATE 0
2346#endif
2347/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002348
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002349#ifdef MS_WINDOWS
2350 #undef PATH_HAVE_FTRUNCATE
2351 #define PATH_HAVE_FTRUNCATE 1
2352#endif
Larry Hastings31826802013-10-19 00:09:25 -07002353
Larry Hastings61272b72014-01-07 12:41:53 -08002354/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002355
2356class path_t_converter(CConverter):
2357
2358 type = "path_t"
2359 impl_by_reference = True
2360 parse_by_reference = True
2361
2362 converter = 'path_converter'
2363
2364 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002365 # right now path_t doesn't support default values.
2366 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002367 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002368 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002369
Larry Hastings2f936352014-08-05 14:04:04 +10002370 if self.c_default not in (None, 'Py_None'):
2371 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002372
2373 self.nullable = nullable
2374 self.allow_fd = allow_fd
2375
Larry Hastings7726ac92014-01-31 22:03:12 -08002376 def pre_render(self):
2377 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002378 if isinstance(value, str):
2379 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002380 return str(int(bool(value)))
2381
2382 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002383 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002384 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002385 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002386 strify(self.nullable),
2387 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002388 )
2389
2390 def cleanup(self):
2391 return "path_cleanup(&" + self.name + ");\n"
2392
2393
2394class dir_fd_converter(CConverter):
2395 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002396
Larry Hastings2f936352014-08-05 14:04:04 +10002397 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002398 if self.default in (unspecified, None):
2399 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002400 if isinstance(requires, str):
2401 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2402 else:
2403 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002404
Larry Hastings2f936352014-08-05 14:04:04 +10002405class fildes_converter(CConverter):
2406 type = 'int'
2407 converter = 'fildes_converter'
2408
2409class uid_t_converter(CConverter):
2410 type = "uid_t"
2411 converter = '_Py_Uid_Converter'
2412
2413class gid_t_converter(CConverter):
2414 type = "gid_t"
2415 converter = '_Py_Gid_Converter'
2416
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002417class dev_t_converter(CConverter):
2418 type = 'dev_t'
2419 converter = '_Py_Dev_Converter'
2420
2421class dev_t_return_converter(unsigned_long_return_converter):
2422 type = 'dev_t'
2423 conversion_fn = '_PyLong_FromDev'
2424 unsigned_cast = '(dev_t)'
2425
Larry Hastings2f936352014-08-05 14:04:04 +10002426class FSConverter_converter(CConverter):
2427 type = 'PyObject *'
2428 converter = 'PyUnicode_FSConverter'
2429 def converter_init(self):
2430 if self.default is not unspecified:
2431 fail("FSConverter_converter does not support default values")
2432 self.c_default = 'NULL'
2433
2434 def cleanup(self):
2435 return "Py_XDECREF(" + self.name + ");\n"
2436
2437class pid_t_converter(CConverter):
2438 type = 'pid_t'
2439 format_unit = '" _Py_PARSE_PID "'
2440
2441class idtype_t_converter(int_converter):
2442 type = 'idtype_t'
2443
2444class id_t_converter(CConverter):
2445 type = 'id_t'
2446 format_unit = '" _Py_PARSE_PID "'
2447
Benjamin Petersonca470632016-09-06 13:47:26 -07002448class intptr_t_converter(CConverter):
2449 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002450 format_unit = '" _Py_PARSE_INTPTR "'
2451
2452class Py_off_t_converter(CConverter):
2453 type = 'Py_off_t'
2454 converter = 'Py_off_t_converter'
2455
2456class Py_off_t_return_converter(long_return_converter):
2457 type = 'Py_off_t'
2458 conversion_fn = 'PyLong_FromPy_off_t'
2459
2460class path_confname_converter(CConverter):
2461 type="int"
2462 converter="conv_path_confname"
2463
2464class confstr_confname_converter(path_confname_converter):
2465 converter='conv_confstr_confname'
2466
2467class sysconf_confname_converter(path_confname_converter):
2468 converter="conv_sysconf_confname"
2469
2470class sched_param_converter(CConverter):
2471 type = 'struct sched_param'
2472 converter = 'convert_sched_param'
2473 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002474
Larry Hastings61272b72014-01-07 12:41:53 -08002475[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002476/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002477
Larry Hastings61272b72014-01-07 12:41:53 -08002478/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002479
Larry Hastings2a727912014-01-16 11:32:01 -08002480os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002481
2482 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002483 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002484 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002485
2486 *
2487
Larry Hastings2f936352014-08-05 14:04:04 +10002488 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002489 If not None, it should be a file descriptor open to a directory,
2490 and path should be a relative string; path will then be relative to
2491 that directory.
2492
2493 follow_symlinks: bool = True
2494 If False, and the last element of the path is a symbolic link,
2495 stat will examine the symbolic link itself instead of the file
2496 the link points to.
2497
2498Perform a stat system call on the given path.
2499
2500dir_fd and follow_symlinks may not be implemented
2501 on your platform. If they are unavailable, using them will raise a
2502 NotImplementedError.
2503
2504It's an error to use dir_fd or follow_symlinks when specifying path as
2505 an open file descriptor.
2506
Larry Hastings61272b72014-01-07 12:41:53 -08002507[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002508
Larry Hastings31826802013-10-19 00:09:25 -07002509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002510os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002511/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002512{
2513 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2514}
2515
Larry Hastings2f936352014-08-05 14:04:04 +10002516
2517/*[clinic input]
2518os.lstat
2519
2520 path : path_t
2521
2522 *
2523
2524 dir_fd : dir_fd(requires='fstatat') = None
2525
2526Perform a stat system call on the given path, without following symbolic links.
2527
2528Like stat(), but do not follow symbolic links.
2529Equivalent to stat(path, follow_symlinks=False).
2530[clinic start generated code]*/
2531
Larry Hastings2f936352014-08-05 14:04:04 +10002532static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002533os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2534/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002535{
2536 int follow_symlinks = 0;
2537 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2538}
Larry Hastings31826802013-10-19 00:09:25 -07002539
Larry Hastings2f936352014-08-05 14:04:04 +10002540
Larry Hastings61272b72014-01-07 12:41:53 -08002541/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002542os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002543
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002544 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002545 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002546
2547 mode: int
2548 Operating-system mode bitfield. Can be F_OK to test existence,
2549 or the inclusive-OR of R_OK, W_OK, and X_OK.
2550
2551 *
2552
Larry Hastings2f936352014-08-05 14:04:04 +10002553 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002554 If not None, it should be a file descriptor open to a directory,
2555 and path should be relative; path will then be relative to that
2556 directory.
2557
2558 effective_ids: bool = False
2559 If True, access will use the effective uid/gid instead of
2560 the real uid/gid.
2561
2562 follow_symlinks: bool = True
2563 If False, and the last element of the path is a symbolic link,
2564 access will examine the symbolic link itself instead of the file
2565 the link points to.
2566
2567Use the real uid/gid to test for access to a path.
2568
2569{parameters}
2570dir_fd, effective_ids, and follow_symlinks may not be implemented
2571 on your platform. If they are unavailable, using them will raise a
2572 NotImplementedError.
2573
2574Note that most operations will use the effective uid/gid, therefore this
2575 routine can be used in a suid/sgid environment to test if the invoking user
2576 has the specified access to the path.
2577
Larry Hastings61272b72014-01-07 12:41:53 -08002578[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002579
Larry Hastings2f936352014-08-05 14:04:04 +10002580static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002581os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002582 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002583/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002584{
Larry Hastings2f936352014-08-05 14:04:04 +10002585 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002586
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002587#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002589#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002590 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002591#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002592
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593#ifndef HAVE_FACCESSAT
2594 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002595 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596
2597 if (effective_ids) {
2598 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002599 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002600 }
2601#endif
2602
2603#ifdef MS_WINDOWS
2604 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002605 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002606 Py_END_ALLOW_THREADS
2607
2608 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002609 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610 * * we didn't get a -1, and
2611 * * write access wasn't requested,
2612 * * or the file isn't read-only,
2613 * * or it's a directory.
2614 * (Directories cannot be read-only on Windows.)
2615 */
Larry Hastings2f936352014-08-05 14:04:04 +10002616 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002617 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002618 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002619 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002620#else
2621
2622 Py_BEGIN_ALLOW_THREADS
2623#ifdef HAVE_FACCESSAT
2624 if ((dir_fd != DEFAULT_DIR_FD) ||
2625 effective_ids ||
2626 !follow_symlinks) {
2627 int flags = 0;
2628 if (!follow_symlinks)
2629 flags |= AT_SYMLINK_NOFOLLOW;
2630 if (effective_ids)
2631 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002632 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002633 }
2634 else
2635#endif
Larry Hastings31826802013-10-19 00:09:25 -07002636 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002637 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002638 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002639#endif
2640
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002642}
2643
Guido van Rossumd371ff11999-01-25 16:12:23 +00002644#ifndef F_OK
2645#define F_OK 0
2646#endif
2647#ifndef R_OK
2648#define R_OK 4
2649#endif
2650#ifndef W_OK
2651#define W_OK 2
2652#endif
2653#ifndef X_OK
2654#define X_OK 1
2655#endif
2656
Larry Hastings31826802013-10-19 00:09:25 -07002657
Guido van Rossumd371ff11999-01-25 16:12:23 +00002658#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002659/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002660os.ttyname -> DecodeFSDefault
2661
2662 fd: int
2663 Integer file descriptor handle.
2664
2665 /
2666
2667Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002668[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002669
Larry Hastings31826802013-10-19 00:09:25 -07002670static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002671os_ttyname_impl(PyObject *module, int fd)
2672/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002673{
2674 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002675
Larry Hastings31826802013-10-19 00:09:25 -07002676 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002677 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002678 posix_error();
2679 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002680}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002681#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002682
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002683#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002684/*[clinic input]
2685os.ctermid
2686
2687Return the name of the controlling terminal for this process.
2688[clinic start generated code]*/
2689
Larry Hastings2f936352014-08-05 14:04:04 +10002690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002691os_ctermid_impl(PyObject *module)
2692/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002693{
Victor Stinner8c62be82010-05-06 00:08:46 +00002694 char *ret;
2695 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002696
Greg Wardb48bc172000-03-01 21:51:56 +00002697#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002698 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002699#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002700 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002701#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002702 if (ret == NULL)
2703 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002704 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002705}
Larry Hastings2f936352014-08-05 14:04:04 +10002706#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002707
Larry Hastings2f936352014-08-05 14:04:04 +10002708
2709/*[clinic input]
2710os.chdir
2711
2712 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2713
2714Change the current working directory to the specified path.
2715
2716path may always be specified as a string.
2717On some platforms, path may also be specified as an open file descriptor.
2718 If this functionality is unavailable, using it raises an exception.
2719[clinic start generated code]*/
2720
Larry Hastings2f936352014-08-05 14:04:04 +10002721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002722os_chdir_impl(PyObject *module, path_t *path)
2723/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002724{
2725 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726
2727 Py_BEGIN_ALLOW_THREADS
2728#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002729 /* on unix, success = 0, on windows, success = !0 */
2730 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002731#else
2732#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002733 if (path->fd != -1)
2734 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735 else
2736#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002737 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002738#endif
2739 Py_END_ALLOW_THREADS
2740
2741 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002742 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002743 }
2744
Larry Hastings2f936352014-08-05 14:04:04 +10002745 Py_RETURN_NONE;
2746}
2747
2748
2749#ifdef HAVE_FCHDIR
2750/*[clinic input]
2751os.fchdir
2752
2753 fd: fildes
2754
2755Change to the directory of the given file descriptor.
2756
2757fd must be opened on a directory, not a file.
2758Equivalent to os.chdir(fd).
2759
2760[clinic start generated code]*/
2761
Fred Drake4d1e64b2002-04-15 19:40:07 +00002762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002763os_fchdir_impl(PyObject *module, int fd)
2764/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002765{
Larry Hastings2f936352014-08-05 14:04:04 +10002766 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002767}
2768#endif /* HAVE_FCHDIR */
2769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Larry Hastings2f936352014-08-05 14:04:04 +10002771/*[clinic input]
2772os.chmod
2773
2774 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002775 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002776 On some platforms, path may also be specified as an open file descriptor.
2777 If this functionality is unavailable, using it raises an exception.
2778
2779 mode: int
2780 Operating-system mode bitfield.
2781
2782 *
2783
2784 dir_fd : dir_fd(requires='fchmodat') = None
2785 If not None, it should be a file descriptor open to a directory,
2786 and path should be relative; path will then be relative to that
2787 directory.
2788
2789 follow_symlinks: bool = True
2790 If False, and the last element of the path is a symbolic link,
2791 chmod will modify the symbolic link itself instead of the file
2792 the link points to.
2793
2794Change the access permissions of a file.
2795
2796It is an error to use dir_fd or follow_symlinks when specifying path as
2797 an open file descriptor.
2798dir_fd and follow_symlinks may not be implemented on your platform.
2799 If they are unavailable, using them will raise a NotImplementedError.
2800
2801[clinic start generated code]*/
2802
Larry Hastings2f936352014-08-05 14:04:04 +10002803static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002804os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002805 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002806/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002807{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002810#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002811 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002813
Larry Hastings9cf065c2012-06-22 16:30:09 -07002814#ifdef HAVE_FCHMODAT
2815 int fchmodat_nofollow_unsupported = 0;
2816#endif
2817
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2819 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002820 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002821#endif
2822
2823#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002825 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002826 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002827 result = 0;
2828 else {
2829 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002830 attr &= ~FILE_ATTRIBUTE_READONLY;
2831 else
2832 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002833 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002834 }
2835 Py_END_ALLOW_THREADS
2836
2837 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002838 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839 }
2840#else /* MS_WINDOWS */
2841 Py_BEGIN_ALLOW_THREADS
2842#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002843 if (path->fd != -1)
2844 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002845 else
2846#endif
2847#ifdef HAVE_LCHMOD
2848 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002849 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850 else
2851#endif
2852#ifdef HAVE_FCHMODAT
2853 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2854 /*
2855 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2856 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002857 * and then says it isn't implemented yet.
2858 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 *
2860 * Once it is supported, os.chmod will automatically
2861 * support dir_fd and follow_symlinks=False. (Hopefully.)
2862 * Until then, we need to be careful what exception we raise.
2863 */
Larry Hastings2f936352014-08-05 14:04:04 +10002864 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2866 /*
2867 * But wait! We can't throw the exception without allowing threads,
2868 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2869 */
2870 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002871 result &&
2872 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2873 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002874 }
2875 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002876#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002877 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002878 Py_END_ALLOW_THREADS
2879
2880 if (result) {
2881#ifdef HAVE_FCHMODAT
2882 if (fchmodat_nofollow_unsupported) {
2883 if (dir_fd != DEFAULT_DIR_FD)
2884 dir_fd_and_follow_symlinks_invalid("chmod",
2885 dir_fd, follow_symlinks);
2886 else
2887 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002888 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002889 }
2890 else
2891#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002892 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893 }
2894#endif
2895
Larry Hastings2f936352014-08-05 14:04:04 +10002896 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002897}
2898
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899
Christian Heimes4e30a842007-11-30 22:12:06 +00002900#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002901/*[clinic input]
2902os.fchmod
2903
2904 fd: int
2905 mode: int
2906
2907Change the access permissions of the file given by file descriptor fd.
2908
2909Equivalent to os.chmod(fd, mode).
2910[clinic start generated code]*/
2911
Larry Hastings2f936352014-08-05 14:04:04 +10002912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002913os_fchmod_impl(PyObject *module, int fd, int mode)
2914/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002915{
2916 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002917 int async_err = 0;
2918
2919 do {
2920 Py_BEGIN_ALLOW_THREADS
2921 res = fchmod(fd, mode);
2922 Py_END_ALLOW_THREADS
2923 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2924 if (res != 0)
2925 return (!async_err) ? posix_error() : NULL;
2926
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002928}
2929#endif /* HAVE_FCHMOD */
2930
Larry Hastings2f936352014-08-05 14:04:04 +10002931
Christian Heimes4e30a842007-11-30 22:12:06 +00002932#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002933/*[clinic input]
2934os.lchmod
2935
2936 path: path_t
2937 mode: int
2938
2939Change the access permissions of a file, without following symbolic links.
2940
2941If path is a symlink, this affects the link itself rather than the target.
2942Equivalent to chmod(path, mode, follow_symlinks=False)."
2943[clinic start generated code]*/
2944
Larry Hastings2f936352014-08-05 14:04:04 +10002945static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002946os_lchmod_impl(PyObject *module, path_t *path, int mode)
2947/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002948{
Victor Stinner8c62be82010-05-06 00:08:46 +00002949 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002950 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002951 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002952 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002953 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002954 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002955 return NULL;
2956 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002957 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002958}
2959#endif /* HAVE_LCHMOD */
2960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002961
Thomas Wouterscf297e42007-02-23 15:07:44 +00002962#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002963/*[clinic input]
2964os.chflags
2965
2966 path: path_t
2967 flags: unsigned_long(bitwise=True)
2968 follow_symlinks: bool=True
2969
2970Set file flags.
2971
2972If follow_symlinks is False, and the last element of the path is a symbolic
2973 link, chflags will change flags on the symbolic link itself instead of the
2974 file the link points to.
2975follow_symlinks may not be implemented on your platform. If it is
2976unavailable, using it will raise a NotImplementedError.
2977
2978[clinic start generated code]*/
2979
Larry Hastings2f936352014-08-05 14:04:04 +10002980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002981os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002982 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002983/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002984{
2985 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986
2987#ifndef HAVE_LCHFLAGS
2988 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002989 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002990#endif
2991
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002993#ifdef HAVE_LCHFLAGS
2994 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002995 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996 else
2997#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002998 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002999 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003000
Larry Hastings2f936352014-08-05 14:04:04 +10003001 if (result)
3002 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003
Larry Hastings2f936352014-08-05 14:04:04 +10003004 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003005}
3006#endif /* HAVE_CHFLAGS */
3007
Larry Hastings2f936352014-08-05 14:04:04 +10003008
Thomas Wouterscf297e42007-02-23 15:07:44 +00003009#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003010/*[clinic input]
3011os.lchflags
3012
3013 path: path_t
3014 flags: unsigned_long(bitwise=True)
3015
3016Set file flags.
3017
3018This function will not follow symbolic links.
3019Equivalent to chflags(path, flags, follow_symlinks=False).
3020[clinic start generated code]*/
3021
Larry Hastings2f936352014-08-05 14:04:04 +10003022static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003023os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3024/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003025{
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003027 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003028 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003029 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003030 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003031 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003032 }
Victor Stinner292c8352012-10-30 02:17:38 +01003033 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003034}
3035#endif /* HAVE_LCHFLAGS */
3036
Larry Hastings2f936352014-08-05 14:04:04 +10003037
Martin v. Löwis244edc82001-10-04 22:44:26 +00003038#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003039/*[clinic input]
3040os.chroot
3041 path: path_t
3042
3043Change root directory to path.
3044
3045[clinic start generated code]*/
3046
Larry Hastings2f936352014-08-05 14:04:04 +10003047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003048os_chroot_impl(PyObject *module, path_t *path)
3049/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003050{
3051 int res;
3052 Py_BEGIN_ALLOW_THREADS
3053 res = chroot(path->narrow);
3054 Py_END_ALLOW_THREADS
3055 if (res < 0)
3056 return path_error(path);
3057 Py_RETURN_NONE;
3058}
3059#endif /* HAVE_CHROOT */
3060
Martin v. Löwis244edc82001-10-04 22:44:26 +00003061
Guido van Rossum21142a01999-01-08 21:05:37 +00003062#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003063/*[clinic input]
3064os.fsync
3065
3066 fd: fildes
3067
3068Force write of fd to disk.
3069[clinic start generated code]*/
3070
Larry Hastings2f936352014-08-05 14:04:04 +10003071static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003072os_fsync_impl(PyObject *module, int fd)
3073/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003074{
3075 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003076}
3077#endif /* HAVE_FSYNC */
3078
Larry Hastings2f936352014-08-05 14:04:04 +10003079
Ross Lagerwall7807c352011-03-17 20:20:30 +02003080#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003081/*[clinic input]
3082os.sync
3083
3084Force write of everything to disk.
3085[clinic start generated code]*/
3086
Larry Hastings2f936352014-08-05 14:04:04 +10003087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003088os_sync_impl(PyObject *module)
3089/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003090{
3091 Py_BEGIN_ALLOW_THREADS
3092 sync();
3093 Py_END_ALLOW_THREADS
3094 Py_RETURN_NONE;
3095}
Larry Hastings2f936352014-08-05 14:04:04 +10003096#endif /* HAVE_SYNC */
3097
Ross Lagerwall7807c352011-03-17 20:20:30 +02003098
Guido van Rossum21142a01999-01-08 21:05:37 +00003099#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003100#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003101extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3102#endif
3103
Larry Hastings2f936352014-08-05 14:04:04 +10003104/*[clinic input]
3105os.fdatasync
3106
3107 fd: fildes
3108
3109Force write of fd to disk without forcing update of metadata.
3110[clinic start generated code]*/
3111
Larry Hastings2f936352014-08-05 14:04:04 +10003112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003113os_fdatasync_impl(PyObject *module, int fd)
3114/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003115{
3116 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003117}
3118#endif /* HAVE_FDATASYNC */
3119
3120
Fredrik Lundh10723342000-07-10 16:38:09 +00003121#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003122/*[clinic input]
3123os.chown
3124
3125 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003126 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003127
3128 uid: uid_t
3129
3130 gid: gid_t
3131
3132 *
3133
3134 dir_fd : dir_fd(requires='fchownat') = None
3135 If not None, it should be a file descriptor open to a directory,
3136 and path should be relative; path will then be relative to that
3137 directory.
3138
3139 follow_symlinks: bool = True
3140 If False, and the last element of the path is a symbolic link,
3141 stat will examine the symbolic link itself instead of the file
3142 the link points to.
3143
3144Change the owner and group id of path to the numeric uid and gid.\
3145
3146path may always be specified as a string.
3147On some platforms, path may also be specified as an open file descriptor.
3148 If this functionality is unavailable, using it raises an exception.
3149If dir_fd is not None, it should be a file descriptor open to a directory,
3150 and path should be relative; path will then be relative to that directory.
3151If follow_symlinks is False, and the last element of the path is a symbolic
3152 link, chown will modify the symbolic link itself instead of the file the
3153 link points to.
3154It is an error to use dir_fd or follow_symlinks when specifying path as
3155 an open file descriptor.
3156dir_fd and follow_symlinks may not be implemented on your platform.
3157 If they are unavailable, using them will raise a NotImplementedError.
3158
3159[clinic start generated code]*/
3160
Larry Hastings2f936352014-08-05 14:04:04 +10003161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003162os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003163 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003164/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003165{
3166 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003167
3168#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3169 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003170 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003171#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003172 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3173 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3174 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175
3176#ifdef __APPLE__
3177 /*
3178 * This is for Mac OS X 10.3, which doesn't have lchown.
3179 * (But we still have an lchown symbol because of weak-linking.)
3180 * It doesn't have fchownat either. So there's no possibility
3181 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003182 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003183 if ((!follow_symlinks) && (lchown == NULL)) {
3184 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003185 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003186 }
3187#endif
3188
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003190#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003191 if (path->fd != -1)
3192 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003193 else
3194#endif
3195#ifdef HAVE_LCHOWN
3196 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003197 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003198 else
3199#endif
3200#ifdef HAVE_FCHOWNAT
3201 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003202 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3204 else
3205#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003206 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003207 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208
Larry Hastings2f936352014-08-05 14:04:04 +10003209 if (result)
3210 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211
Larry Hastings2f936352014-08-05 14:04:04 +10003212 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003213}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003214#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003215
Larry Hastings2f936352014-08-05 14:04:04 +10003216
Christian Heimes4e30a842007-11-30 22:12:06 +00003217#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003218/*[clinic input]
3219os.fchown
3220
3221 fd: int
3222 uid: uid_t
3223 gid: gid_t
3224
3225Change the owner and group id of the file specified by file descriptor.
3226
3227Equivalent to os.chown(fd, uid, gid).
3228
3229[clinic start generated code]*/
3230
Larry Hastings2f936352014-08-05 14:04:04 +10003231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003232os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3233/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003234{
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003236 int async_err = 0;
3237
3238 do {
3239 Py_BEGIN_ALLOW_THREADS
3240 res = fchown(fd, uid, gid);
3241 Py_END_ALLOW_THREADS
3242 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3243 if (res != 0)
3244 return (!async_err) ? posix_error() : NULL;
3245
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003247}
3248#endif /* HAVE_FCHOWN */
3249
Larry Hastings2f936352014-08-05 14:04:04 +10003250
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003251#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003252/*[clinic input]
3253os.lchown
3254
3255 path : path_t
3256 uid: uid_t
3257 gid: gid_t
3258
3259Change the owner and group id of path to the numeric uid and gid.
3260
3261This function will not follow symbolic links.
3262Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3263[clinic start generated code]*/
3264
Larry Hastings2f936352014-08-05 14:04:04 +10003265static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003266os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3267/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003268{
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003270 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003271 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003272 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003273 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003274 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003275 }
Larry Hastings2f936352014-08-05 14:04:04 +10003276 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003277}
3278#endif /* HAVE_LCHOWN */
3279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280
Barry Warsaw53699e91996-12-10 23:23:01 +00003281static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003282posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003283{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003284 char *buf, *tmpbuf;
3285 char *cwd;
3286 const size_t chunk = 1024;
3287 size_t buflen = 0;
3288 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003289
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003290#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003292 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 wchar_t *wbuf2 = wbuf;
3294 PyObject *resobj;
3295 DWORD len;
3296 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003297 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 /* If the buffer is large enough, len does not include the
3299 terminating \0. If the buffer is too small, len includes
3300 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003301 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003302 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003303 if (wbuf2)
3304 len = GetCurrentDirectoryW(len, wbuf2);
3305 }
3306 Py_END_ALLOW_THREADS
3307 if (!wbuf2) {
3308 PyErr_NoMemory();
3309 return NULL;
3310 }
3311 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003312 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003313 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003314 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003315 }
3316 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003317 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003318 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003319 return resobj;
3320 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003321
3322 if (win32_warn_bytes_api())
3323 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003324#endif
3325
Victor Stinner4403d7d2015-04-25 00:16:10 +02003326 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003327 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003328 do {
3329 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003330#ifdef MS_WINDOWS
3331 if (buflen > INT_MAX) {
3332 PyErr_NoMemory();
3333 break;
3334 }
3335#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 tmpbuf = PyMem_RawRealloc(buf, buflen);
3337 if (tmpbuf == NULL)
3338 break;
3339
3340 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003341#ifdef MS_WINDOWS
3342 cwd = getcwd(buf, (int)buflen);
3343#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003344 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003345#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003346 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003348
3349 if (cwd == NULL) {
3350 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003351 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003352 }
3353
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003355 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3356 else
3357 obj = PyUnicode_DecodeFSDefault(buf);
3358 PyMem_RawFree(buf);
3359
3360 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003361}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003362
Larry Hastings2f936352014-08-05 14:04:04 +10003363
3364/*[clinic input]
3365os.getcwd
3366
3367Return a unicode string representing the current working directory.
3368[clinic start generated code]*/
3369
Larry Hastings2f936352014-08-05 14:04:04 +10003370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003371os_getcwd_impl(PyObject *module)
3372/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003373{
3374 return posix_getcwd(0);
3375}
3376
Larry Hastings2f936352014-08-05 14:04:04 +10003377
3378/*[clinic input]
3379os.getcwdb
3380
3381Return a bytes string representing the current working directory.
3382[clinic start generated code]*/
3383
Larry Hastings2f936352014-08-05 14:04:04 +10003384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003385os_getcwdb_impl(PyObject *module)
3386/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003387{
3388 return posix_getcwd(1);
3389}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003390
Larry Hastings2f936352014-08-05 14:04:04 +10003391
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3393#define HAVE_LINK 1
3394#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003395
Guido van Rossumb6775db1994-08-01 11:34:53 +00003396#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003397/*[clinic input]
3398
3399os.link
3400
3401 src : path_t
3402 dst : path_t
3403 *
3404 src_dir_fd : dir_fd = None
3405 dst_dir_fd : dir_fd = None
3406 follow_symlinks: bool = True
3407
3408Create a hard link to a file.
3409
3410If either src_dir_fd or dst_dir_fd is not None, it should be a file
3411 descriptor open to a directory, and the respective path string (src or dst)
3412 should be relative; the path will then be relative to that directory.
3413If follow_symlinks is False, and the last element of src is a symbolic
3414 link, link will create a link to the symbolic link itself instead of the
3415 file the link points to.
3416src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3417 platform. If they are unavailable, using them will raise a
3418 NotImplementedError.
3419[clinic start generated code]*/
3420
Larry Hastings2f936352014-08-05 14:04:04 +10003421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003422os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003423 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003424/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003425{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003427 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428#else
3429 int result;
3430#endif
3431
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432#ifndef HAVE_LINKAT
3433 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3434 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003435 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436 }
3437#endif
3438
Steve Dowercc16be82016-09-08 10:35:16 -07003439#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003440 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 PyErr_SetString(PyExc_NotImplementedError,
3442 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 }
Steve Dowercc16be82016-09-08 10:35:16 -07003445#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003446
Brian Curtin1b9df392010-11-24 20:24:31 +00003447#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003449 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003451
Larry Hastings2f936352014-08-05 14:04:04 +10003452 if (!result)
3453 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454#else
3455 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003456#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3458 (dst_dir_fd != DEFAULT_DIR_FD) ||
3459 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003460 result = linkat(src_dir_fd, src->narrow,
3461 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3463 else
Steve Dowercc16be82016-09-08 10:35:16 -07003464#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003465 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003467
Larry Hastings2f936352014-08-05 14:04:04 +10003468 if (result)
3469 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003470#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471
Larry Hastings2f936352014-08-05 14:04:04 +10003472 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003473}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474#endif
3475
Brian Curtin1b9df392010-11-24 20:24:31 +00003476
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003477#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003478static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003479_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003480{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 PyObject *v;
3482 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3483 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003484 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003486 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003488
Steve Dowercc16be82016-09-08 10:35:16 -07003489 WIN32_FIND_DATAW wFileData;
3490 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003491
Steve Dowercc16be82016-09-08 10:35:16 -07003492 if (!path->wide) { /* Default arg: "." */
3493 po_wchars = L".";
3494 len = 1;
3495 } else {
3496 po_wchars = path->wide;
3497 len = wcslen(path->wide);
3498 }
3499 /* The +5 is so we can append "\\*.*\0" */
3500 wnamebuf = PyMem_New(wchar_t, len + 5);
3501 if (!wnamebuf) {
3502 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 }
Steve Dowercc16be82016-09-08 10:35:16 -07003505 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003507 wchar_t wch = wnamebuf[len-1];
3508 if (wch != SEP && wch != ALTSEP && wch != L':')
3509 wnamebuf[len++] = SEP;
3510 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 }
Steve Dowercc16be82016-09-08 10:35:16 -07003512 if ((list = PyList_New(0)) == NULL) {
3513 goto exit;
3514 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003515 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003516 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003517 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 if (hFindFile == INVALID_HANDLE_VALUE) {
3519 int error = GetLastError();
3520 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003521 goto exit;
3522 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003523 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 }
3526 do {
3527 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003528 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3529 wcscmp(wFileData.cFileName, L"..") != 0) {
3530 v = PyUnicode_FromWideChar(wFileData.cFileName,
3531 wcslen(wFileData.cFileName));
3532 if (path->narrow && v) {
3533 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3534 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 Py_DECREF(list);
3537 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 break;
3539 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542 Py_DECREF(list);
3543 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 break;
3545 }
3546 Py_DECREF(v);
3547 }
3548 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003549 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 Py_END_ALLOW_THREADS
3551 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3552 it got to the end of the directory. */
3553 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003555 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 }
3558 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003559
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560exit:
3561 if (hFindFile != INVALID_HANDLE_VALUE) {
3562 if (FindClose(hFindFile) == FALSE) {
3563 if (list != NULL) {
3564 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003565 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 }
3567 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003569 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003570
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003572} /* end of _listdir_windows_no_opendir */
3573
3574#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3575
3576static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003577_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003578{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003579 PyObject *v;
3580 DIR *dirp = NULL;
3581 struct dirent *ep;
3582 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003583#ifdef HAVE_FDOPENDIR
3584 int fd = -1;
3585#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003586
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003588#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003589 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003591 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003592 if (fd == -1)
3593 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594
Larry Hastingsfdaea062012-06-25 04:42:23 -07003595 return_str = 1;
3596
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597 Py_BEGIN_ALLOW_THREADS
3598 dirp = fdopendir(fd);
3599 Py_END_ALLOW_THREADS
3600 }
3601 else
3602#endif
3603 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003604 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003605 if (path->narrow) {
3606 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003607 /* only return bytes if they specified a bytes-like object */
3608 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003609 }
3610 else {
3611 name = ".";
3612 return_str = 1;
3613 }
3614
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 Py_BEGIN_ALLOW_THREADS
3616 dirp = opendir(name);
3617 Py_END_ALLOW_THREADS
3618 }
3619
3620 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003621 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003622#ifdef HAVE_FDOPENDIR
3623 if (fd != -1) {
3624 Py_BEGIN_ALLOW_THREADS
3625 close(fd);
3626 Py_END_ALLOW_THREADS
3627 }
3628#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 goto exit;
3630 }
3631 if ((list = PyList_New(0)) == NULL) {
3632 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 }
3634 for (;;) {
3635 errno = 0;
3636 Py_BEGIN_ALLOW_THREADS
3637 ep = readdir(dirp);
3638 Py_END_ALLOW_THREADS
3639 if (ep == NULL) {
3640 if (errno == 0) {
3641 break;
3642 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003643 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003644 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 }
3647 }
3648 if (ep->d_name[0] == '.' &&
3649 (NAMLEN(ep) == 1 ||
3650 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3651 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003652 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003653 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3654 else
3655 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003656 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 break;
3659 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 break;
3664 }
3665 Py_DECREF(v);
3666 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003667
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668exit:
3669 if (dirp != NULL) {
3670 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003671#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 if (fd > -1)
3673 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003674#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003675 closedir(dirp);
3676 Py_END_ALLOW_THREADS
3677 }
3678
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003680} /* end of _posix_listdir */
3681#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003682
Larry Hastings2f936352014-08-05 14:04:04 +10003683
3684/*[clinic input]
3685os.listdir
3686
3687 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3688
3689Return a list containing the names of the files in the directory.
3690
BNMetricsb9427072018-11-02 15:20:19 +00003691path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003692 the filenames returned will also be bytes; in all other circumstances
3693 the filenames returned will be str.
3694If path is None, uses the path='.'.
3695On some platforms, path may also be specified as an open file descriptor;\
3696 the file descriptor must refer to a directory.
3697 If this functionality is unavailable, using it raises NotImplementedError.
3698
3699The list is in arbitrary order. It does not include the special
3700entries '.' and '..' even if they are present in the directory.
3701
3702
3703[clinic start generated code]*/
3704
Larry Hastings2f936352014-08-05 14:04:04 +10003705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003706os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003707/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003708{
3709#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3710 return _listdir_windows_no_opendir(path, NULL);
3711#else
3712 return _posix_listdir(path, NULL);
3713#endif
3714}
3715
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003716#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003717/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003718/*[clinic input]
3719os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003720
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003721 path: path_t
3722 /
3723
3724[clinic start generated code]*/
3725
3726static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003727os__getfullpathname_impl(PyObject *module, path_t *path)
3728/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003729{
Steve Dowercc16be82016-09-08 10:35:16 -07003730 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3731 wchar_t *wtemp;
3732 DWORD result;
3733 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003734
Steve Dowercc16be82016-09-08 10:35:16 -07003735 result = GetFullPathNameW(path->wide,
3736 Py_ARRAY_LENGTH(woutbuf),
3737 woutbuf, &wtemp);
3738 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3739 woutbufp = PyMem_New(wchar_t, result);
3740 if (!woutbufp)
3741 return PyErr_NoMemory();
3742 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003743 }
Steve Dowercc16be82016-09-08 10:35:16 -07003744 if (result) {
3745 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3746 if (path->narrow)
3747 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3748 } else
3749 v = win32_error_object("GetFullPathNameW", path->object);
3750 if (woutbufp != woutbuf)
3751 PyMem_Free(woutbufp);
3752 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003753}
Brian Curtind40e6f72010-07-08 21:39:08 +00003754
Brian Curtind25aef52011-06-13 15:16:04 -05003755
Larry Hastings2f936352014-08-05 14:04:04 +10003756/*[clinic input]
3757os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003758
Steve Dower23ad6d02018-02-22 10:39:10 -08003759 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003760 /
3761
3762A helper function for samepath on windows.
3763[clinic start generated code]*/
3764
Larry Hastings2f936352014-08-05 14:04:04 +10003765static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003766os__getfinalpathname_impl(PyObject *module, path_t *path)
3767/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003768{
3769 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003770 wchar_t buf[MAXPATHLEN], *target_path = buf;
3771 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003772 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003773 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003774
Steve Dower23ad6d02018-02-22 10:39:10 -08003775 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003776 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003777 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003778 0, /* desired access */
3779 0, /* share mode */
3780 NULL, /* security attributes */
3781 OPEN_EXISTING,
3782 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3783 FILE_FLAG_BACKUP_SEMANTICS,
3784 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003785 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003786
Steve Dower23ad6d02018-02-22 10:39:10 -08003787 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003788 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003789 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003790
3791 /* We have a good handle to the target, use it to determine the
3792 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003793 while (1) {
3794 Py_BEGIN_ALLOW_THREADS
3795 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3796 buf_size, VOLUME_NAME_DOS);
3797 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003798
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003799 if (!result_length) {
3800 result = win32_error_object("GetFinalPathNameByHandleW",
3801 path->object);
3802 goto cleanup;
3803 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003804
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003805 if (result_length < buf_size) {
3806 break;
3807 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003808
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003809 wchar_t *tmp;
3810 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3811 result_length * sizeof(*tmp));
3812 if (!tmp) {
3813 result = PyErr_NoMemory();
3814 goto cleanup;
3815 }
3816
3817 buf_size = result_length;
3818 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003819 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003820
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003821 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003822 if (path->narrow)
3823 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003824
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003825cleanup:
3826 if (target_path != buf) {
3827 PyMem_Free(target_path);
3828 }
3829 CloseHandle(hFile);
3830 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003831}
Brian Curtin62857742010-09-06 17:07:27 +00003832
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003833/*[clinic input]
3834os._isdir
3835
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003836 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003837 /
3838
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003839Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003840[clinic start generated code]*/
3841
Brian Curtin9c669cc2011-06-08 18:17:18 -05003842static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003843os__isdir(PyObject *module, PyObject *arg)
3844/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003845{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003846 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003847 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3848
3849 if (!path_converter(arg, &path)) {
3850 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3851 PyErr_Clear();
3852 Py_RETURN_FALSE;
3853 }
3854 return NULL;
3855 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003856
Steve Dowerb22a6772016-07-17 20:49:38 -07003857 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003858 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003859 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003860
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003861 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003862 if (attributes == INVALID_FILE_ATTRIBUTES)
3863 Py_RETURN_FALSE;
3864
Brian Curtin9c669cc2011-06-08 18:17:18 -05003865 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3866 Py_RETURN_TRUE;
3867 else
3868 Py_RETURN_FALSE;
3869}
Tim Golden6b528062013-08-01 12:44:00 +01003870
Tim Golden6b528062013-08-01 12:44:00 +01003871
Larry Hastings2f936352014-08-05 14:04:04 +10003872/*[clinic input]
3873os._getvolumepathname
3874
Steve Dower23ad6d02018-02-22 10:39:10 -08003875 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003876
3877A helper function for ismount on Win32.
3878[clinic start generated code]*/
3879
Larry Hastings2f936352014-08-05 14:04:04 +10003880static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003881os__getvolumepathname_impl(PyObject *module, path_t *path)
3882/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003883{
3884 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003885 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003886 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003887 BOOL ret;
3888
Tim Golden6b528062013-08-01 12:44:00 +01003889 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003890 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003891
Victor Stinner850a18e2017-10-24 16:53:32 -07003892 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003893 PyErr_SetString(PyExc_OverflowError, "path too long");
3894 return NULL;
3895 }
3896
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003897 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003898 if (mountpath == NULL)
3899 return PyErr_NoMemory();
3900
3901 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003902 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003903 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003904 Py_END_ALLOW_THREADS
3905
3906 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003907 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003908 goto exit;
3909 }
3910 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003911 if (path->narrow)
3912 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003913
3914exit:
3915 PyMem_Free(mountpath);
3916 return result;
3917}
Tim Golden6b528062013-08-01 12:44:00 +01003918
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003919#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003920
Larry Hastings2f936352014-08-05 14:04:04 +10003921
3922/*[clinic input]
3923os.mkdir
3924
3925 path : path_t
3926
3927 mode: int = 0o777
3928
3929 *
3930
3931 dir_fd : dir_fd(requires='mkdirat') = None
3932
3933# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3934
3935Create a directory.
3936
3937If dir_fd is not None, it should be a file descriptor open to a directory,
3938 and path should be relative; path will then be relative to that directory.
3939dir_fd may not be implemented on your platform.
3940 If it is unavailable, using it will raise a NotImplementedError.
3941
3942The mode argument is ignored on Windows.
3943[clinic start generated code]*/
3944
Larry Hastings2f936352014-08-05 14:04:04 +10003945static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003946os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3947/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003948{
3949 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003950
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003951#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003953 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003955
Larry Hastings2f936352014-08-05 14:04:04 +10003956 if (!result)
3957 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003959 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003960#if HAVE_MKDIRAT
3961 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003962 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003963 else
3964#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003965#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003966 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003967#else
Larry Hastings2f936352014-08-05 14:04:04 +10003968 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003969#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003971 if (result < 0)
3972 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003973#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003974 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003975}
3976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003977
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003978/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3979#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003980#include <sys/resource.h>
3981#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003982
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003983
3984#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003985/*[clinic input]
3986os.nice
3987
3988 increment: int
3989 /
3990
3991Add increment to the priority of process and return the new priority.
3992[clinic start generated code]*/
3993
Larry Hastings2f936352014-08-05 14:04:04 +10003994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003995os_nice_impl(PyObject *module, int increment)
3996/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003997{
3998 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003999
Victor Stinner8c62be82010-05-06 00:08:46 +00004000 /* There are two flavours of 'nice': one that returns the new
4001 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004002 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004003 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004004
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 If we are of the nice family that returns the new priority, we
4006 need to clear errno before the call, and check if errno is filled
4007 before calling posix_error() on a returnvalue of -1, because the
4008 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004009
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 errno = 0;
4011 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004012#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 if (value == 0)
4014 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004015#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 if (value == -1 && errno != 0)
4017 /* either nice() or getpriority() returned an error */
4018 return posix_error();
4019 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004020}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004021#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004022
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004023
4024#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004025/*[clinic input]
4026os.getpriority
4027
4028 which: int
4029 who: int
4030
4031Return program scheduling priority.
4032[clinic start generated code]*/
4033
Larry Hastings2f936352014-08-05 14:04:04 +10004034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004035os_getpriority_impl(PyObject *module, int which, int who)
4036/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004037{
4038 int retval;
4039
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004040 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004041 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004042 if (errno != 0)
4043 return posix_error();
4044 return PyLong_FromLong((long)retval);
4045}
4046#endif /* HAVE_GETPRIORITY */
4047
4048
4049#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004050/*[clinic input]
4051os.setpriority
4052
4053 which: int
4054 who: int
4055 priority: int
4056
4057Set program scheduling priority.
4058[clinic start generated code]*/
4059
Larry Hastings2f936352014-08-05 14:04:04 +10004060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004061os_setpriority_impl(PyObject *module, int which, int who, int priority)
4062/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004063{
4064 int retval;
4065
4066 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004067 if (retval == -1)
4068 return posix_error();
4069 Py_RETURN_NONE;
4070}
4071#endif /* HAVE_SETPRIORITY */
4072
4073
Barry Warsaw53699e91996-12-10 23:23:01 +00004074static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004075internal_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 +00004076{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004077 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004080#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004081 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004082 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004083#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004084 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004085#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4088 (dst_dir_fd != DEFAULT_DIR_FD);
4089#ifndef HAVE_RENAMEAT
4090 if (dir_fd_specified) {
4091 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004092 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093 }
4094#endif
4095
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096#ifdef MS_WINDOWS
4097 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004098 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004099 Py_END_ALLOW_THREADS
4100
Larry Hastings2f936352014-08-05 14:04:04 +10004101 if (!result)
4102 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004103
4104#else
Steve Dowercc16be82016-09-08 10:35:16 -07004105 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4106 PyErr_Format(PyExc_ValueError,
4107 "%s: src and dst must be the same type", function_name);
4108 return NULL;
4109 }
4110
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 Py_BEGIN_ALLOW_THREADS
4112#ifdef HAVE_RENAMEAT
4113 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004114 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115 else
4116#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004117 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118 Py_END_ALLOW_THREADS
4119
Larry Hastings2f936352014-08-05 14:04:04 +10004120 if (result)
4121 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004123 Py_RETURN_NONE;
4124}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004125
Larry Hastings2f936352014-08-05 14:04:04 +10004126
4127/*[clinic input]
4128os.rename
4129
4130 src : path_t
4131 dst : path_t
4132 *
4133 src_dir_fd : dir_fd = None
4134 dst_dir_fd : dir_fd = None
4135
4136Rename a file or directory.
4137
4138If either src_dir_fd or dst_dir_fd is not None, it should be a file
4139 descriptor open to a directory, and the respective path string (src or dst)
4140 should be relative; the path will then be relative to that directory.
4141src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4142 If they are unavailable, using them will raise a NotImplementedError.
4143[clinic start generated code]*/
4144
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004145static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004146os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004147 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004148/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004149{
Larry Hastings2f936352014-08-05 14:04:04 +10004150 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004151}
4152
Larry Hastings2f936352014-08-05 14:04:04 +10004153
4154/*[clinic input]
4155os.replace = os.rename
4156
4157Rename a file or directory, overwriting the destination.
4158
4159If either src_dir_fd or dst_dir_fd is not None, it should be a file
4160 descriptor open to a directory, and the respective path string (src or dst)
4161 should be relative; the path will then be relative to that directory.
4162src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4163 If they are unavailable, using them will raise a NotImplementedError."
4164[clinic start generated code]*/
4165
Larry Hastings2f936352014-08-05 14:04:04 +10004166static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004167os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4168 int dst_dir_fd)
4169/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004170{
4171 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4172}
4173
4174
4175/*[clinic input]
4176os.rmdir
4177
4178 path: path_t
4179 *
4180 dir_fd: dir_fd(requires='unlinkat') = None
4181
4182Remove a directory.
4183
4184If dir_fd is not None, it should be a file descriptor open to a directory,
4185 and path should be relative; path will then be relative to that directory.
4186dir_fd may not be implemented on your platform.
4187 If it is unavailable, using it will raise a NotImplementedError.
4188[clinic start generated code]*/
4189
Larry Hastings2f936352014-08-05 14:04:04 +10004190static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004191os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4192/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004193{
4194 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004195
4196 Py_BEGIN_ALLOW_THREADS
4197#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004198 /* Windows, success=1, UNIX, success=0 */
4199 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004200#else
4201#ifdef HAVE_UNLINKAT
4202 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004203 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004204 else
4205#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004206 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004207#endif
4208 Py_END_ALLOW_THREADS
4209
Larry Hastings2f936352014-08-05 14:04:04 +10004210 if (result)
4211 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004212
Larry Hastings2f936352014-08-05 14:04:04 +10004213 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004214}
4215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004216
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004217#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004218#ifdef MS_WINDOWS
4219/*[clinic input]
4220os.system -> long
4221
4222 command: Py_UNICODE
4223
4224Execute the command in a subshell.
4225[clinic start generated code]*/
4226
Larry Hastings2f936352014-08-05 14:04:04 +10004227static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004228os_system_impl(PyObject *module, Py_UNICODE *command)
4229/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004230{
4231 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004232 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004233 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004234 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004235 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004237 return result;
4238}
4239#else /* MS_WINDOWS */
4240/*[clinic input]
4241os.system -> long
4242
4243 command: FSConverter
4244
4245Execute the command in a subshell.
4246[clinic start generated code]*/
4247
Larry Hastings2f936352014-08-05 14:04:04 +10004248static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004249os_system_impl(PyObject *module, PyObject *command)
4250/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004251{
4252 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004253 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004254 Py_BEGIN_ALLOW_THREADS
4255 result = system(bytes);
4256 Py_END_ALLOW_THREADS
4257 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004258}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004259#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004260#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004262
Larry Hastings2f936352014-08-05 14:04:04 +10004263/*[clinic input]
4264os.umask
4265
4266 mask: int
4267 /
4268
4269Set the current numeric umask and return the previous umask.
4270[clinic start generated code]*/
4271
Larry Hastings2f936352014-08-05 14:04:04 +10004272static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004273os_umask_impl(PyObject *module, int mask)
4274/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004275{
4276 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004277 if (i < 0)
4278 return posix_error();
4279 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004280}
4281
Brian Curtind40e6f72010-07-08 21:39:08 +00004282#ifdef MS_WINDOWS
4283
4284/* override the default DeleteFileW behavior so that directory
4285symlinks can be removed with this function, the same as with
4286Unix symlinks */
4287BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4288{
4289 WIN32_FILE_ATTRIBUTE_DATA info;
4290 WIN32_FIND_DATAW find_data;
4291 HANDLE find_data_handle;
4292 int is_directory = 0;
4293 int is_link = 0;
4294
4295 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4296 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004297
Brian Curtind40e6f72010-07-08 21:39:08 +00004298 /* Get WIN32_FIND_DATA structure for the path to determine if
4299 it is a symlink */
4300 if(is_directory &&
4301 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4302 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4303
4304 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004305 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4306 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4307 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4308 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004309 FindClose(find_data_handle);
4310 }
4311 }
4312 }
4313
4314 if (is_directory && is_link)
4315 return RemoveDirectoryW(lpFileName);
4316
4317 return DeleteFileW(lpFileName);
4318}
4319#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004321
Larry Hastings2f936352014-08-05 14:04:04 +10004322/*[clinic input]
4323os.unlink
4324
4325 path: path_t
4326 *
4327 dir_fd: dir_fd(requires='unlinkat')=None
4328
4329Remove a file (same as remove()).
4330
4331If dir_fd is not None, it should be a file descriptor open to a directory,
4332 and path should be relative; path will then be relative to that directory.
4333dir_fd may not be implemented on your platform.
4334 If it is unavailable, using it will raise a NotImplementedError.
4335
4336[clinic start generated code]*/
4337
Larry Hastings2f936352014-08-05 14:04:04 +10004338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004339os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4340/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004341{
4342 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004343
4344 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004345 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004347 /* Windows, success=1, UNIX, success=0 */
4348 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004349#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004350#ifdef HAVE_UNLINKAT
4351 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004352 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004353 else
4354#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004355 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004356#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004357 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004358 Py_END_ALLOW_THREADS
4359
Larry Hastings2f936352014-08-05 14:04:04 +10004360 if (result)
4361 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004362
Larry Hastings2f936352014-08-05 14:04:04 +10004363 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004364}
4365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004366
Larry Hastings2f936352014-08-05 14:04:04 +10004367/*[clinic input]
4368os.remove = os.unlink
4369
4370Remove a file (same as unlink()).
4371
4372If dir_fd is not None, it should be a file descriptor open to a directory,
4373 and path should be relative; path will then be relative to that directory.
4374dir_fd may not be implemented on your platform.
4375 If it is unavailable, using it will raise a NotImplementedError.
4376[clinic start generated code]*/
4377
Larry Hastings2f936352014-08-05 14:04:04 +10004378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004379os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4380/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004381{
4382 return os_unlink_impl(module, path, dir_fd);
4383}
4384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004385
Larry Hastings605a62d2012-06-24 04:33:36 -07004386static PyStructSequence_Field uname_result_fields[] = {
4387 {"sysname", "operating system name"},
4388 {"nodename", "name of machine on network (implementation-defined)"},
4389 {"release", "operating system release"},
4390 {"version", "operating system version"},
4391 {"machine", "hardware identifier"},
4392 {NULL}
4393};
4394
4395PyDoc_STRVAR(uname_result__doc__,
4396"uname_result: Result from os.uname().\n\n\
4397This object may be accessed either as a tuple of\n\
4398 (sysname, nodename, release, version, machine),\n\
4399or via the attributes sysname, nodename, release, version, and machine.\n\
4400\n\
4401See os.uname for more information.");
4402
4403static PyStructSequence_Desc uname_result_desc = {
4404 "uname_result", /* name */
4405 uname_result__doc__, /* doc */
4406 uname_result_fields,
4407 5
4408};
4409
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004410static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004411
4412
4413#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004414/*[clinic input]
4415os.uname
4416
4417Return an object identifying the current operating system.
4418
4419The object behaves like a named tuple with the following fields:
4420 (sysname, nodename, release, version, machine)
4421
4422[clinic start generated code]*/
4423
Larry Hastings2f936352014-08-05 14:04:04 +10004424static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004425os_uname_impl(PyObject *module)
4426/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004427{
Victor Stinner8c62be82010-05-06 00:08:46 +00004428 struct utsname u;
4429 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004430 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004431
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 Py_BEGIN_ALLOW_THREADS
4433 res = uname(&u);
4434 Py_END_ALLOW_THREADS
4435 if (res < 0)
4436 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004437
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004438 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004439 if (value == NULL)
4440 return NULL;
4441
4442#define SET(i, field) \
4443 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004444 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004445 if (!o) { \
4446 Py_DECREF(value); \
4447 return NULL; \
4448 } \
4449 PyStructSequence_SET_ITEM(value, i, o); \
4450 } \
4451
4452 SET(0, u.sysname);
4453 SET(1, u.nodename);
4454 SET(2, u.release);
4455 SET(3, u.version);
4456 SET(4, u.machine);
4457
4458#undef SET
4459
4460 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004461}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004462#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004463
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004464
Larry Hastings9cf065c2012-06-22 16:30:09 -07004465
4466typedef struct {
4467 int now;
4468 time_t atime_s;
4469 long atime_ns;
4470 time_t mtime_s;
4471 long mtime_ns;
4472} utime_t;
4473
4474/*
Victor Stinner484df002014-10-09 13:52:31 +02004475 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476 * they also intentionally leak the declaration of a pointer named "time"
4477 */
4478#define UTIME_TO_TIMESPEC \
4479 struct timespec ts[2]; \
4480 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004481 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004482 time = NULL; \
4483 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004484 ts[0].tv_sec = ut->atime_s; \
4485 ts[0].tv_nsec = ut->atime_ns; \
4486 ts[1].tv_sec = ut->mtime_s; \
4487 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004488 time = ts; \
4489 } \
4490
4491#define UTIME_TO_TIMEVAL \
4492 struct timeval tv[2]; \
4493 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004494 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004495 time = NULL; \
4496 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004497 tv[0].tv_sec = ut->atime_s; \
4498 tv[0].tv_usec = ut->atime_ns / 1000; \
4499 tv[1].tv_sec = ut->mtime_s; \
4500 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004501 time = tv; \
4502 } \
4503
4504#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004505 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004506 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004507 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004508 time = NULL; \
4509 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004510 u.actime = ut->atime_s; \
4511 u.modtime = ut->mtime_s; \
4512 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513 }
4514
4515#define UTIME_TO_TIME_T \
4516 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004517 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004518 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519 time = NULL; \
4520 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004521 timet[0] = ut->atime_s; \
4522 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004523 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 } \
4525
4526
Victor Stinner528a9ab2015-09-03 21:30:26 +02004527#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004528
4529static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004530utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531{
4532#ifdef HAVE_UTIMENSAT
4533 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4534 UTIME_TO_TIMESPEC;
4535 return utimensat(dir_fd, path, time, flags);
4536#elif defined(HAVE_FUTIMESAT)
4537 UTIME_TO_TIMEVAL;
4538 /*
4539 * follow_symlinks will never be false here;
4540 * we only allow !follow_symlinks and dir_fd together
4541 * if we have utimensat()
4542 */
4543 assert(follow_symlinks);
4544 return futimesat(dir_fd, path, time);
4545#endif
4546}
4547
Larry Hastings2f936352014-08-05 14:04:04 +10004548 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4549#else
4550 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551#endif
4552
Victor Stinner528a9ab2015-09-03 21:30:26 +02004553#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554
4555static int
Victor Stinner484df002014-10-09 13:52:31 +02004556utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004557{
4558#ifdef HAVE_FUTIMENS
4559 UTIME_TO_TIMESPEC;
4560 return futimens(fd, time);
4561#else
4562 UTIME_TO_TIMEVAL;
4563 return futimes(fd, time);
4564#endif
4565}
4566
Larry Hastings2f936352014-08-05 14:04:04 +10004567 #define PATH_UTIME_HAVE_FD 1
4568#else
4569 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570#endif
4571
Victor Stinner5ebae872015-09-22 01:29:33 +02004572#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4573# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4574#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575
Victor Stinner4552ced2015-09-21 22:37:15 +02004576#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577
4578static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004579utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580{
4581#ifdef HAVE_UTIMENSAT
4582 UTIME_TO_TIMESPEC;
4583 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4584#else
4585 UTIME_TO_TIMEVAL;
4586 return lutimes(path, time);
4587#endif
4588}
4589
4590#endif
4591
4592#ifndef MS_WINDOWS
4593
4594static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004595utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004596{
4597#ifdef HAVE_UTIMENSAT
4598 UTIME_TO_TIMESPEC;
4599 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4600#elif defined(HAVE_UTIMES)
4601 UTIME_TO_TIMEVAL;
4602 return utimes(path, time);
4603#elif defined(HAVE_UTIME_H)
4604 UTIME_TO_UTIMBUF;
4605 return utime(path, time);
4606#else
4607 UTIME_TO_TIME_T;
4608 return utime(path, time);
4609#endif
4610}
4611
4612#endif
4613
Larry Hastings76ad59b2012-05-03 00:30:07 -07004614static int
4615split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4616{
4617 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004618 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004619 divmod = PyNumber_Divmod(py_long, billion);
4620 if (!divmod)
4621 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004622 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4623 PyErr_Format(PyExc_TypeError,
4624 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4625 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4626 goto exit;
4627 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004628 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4629 if ((*s == -1) && PyErr_Occurred())
4630 goto exit;
4631 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004632 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004633 goto exit;
4634
4635 result = 1;
4636exit:
4637 Py_XDECREF(divmod);
4638 return result;
4639}
4640
Larry Hastings2f936352014-08-05 14:04:04 +10004641
4642/*[clinic input]
4643os.utime
4644
4645 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4646 times: object = NULL
4647 *
4648 ns: object = NULL
4649 dir_fd: dir_fd(requires='futimensat') = None
4650 follow_symlinks: bool=True
4651
Martin Panter0ff89092015-09-09 01:56:53 +00004652# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004653
4654Set the access and modified time of path.
4655
4656path may always be specified as a string.
4657On some platforms, path may also be specified as an open file descriptor.
4658 If this functionality is unavailable, using it raises an exception.
4659
4660If times is not None, it must be a tuple (atime, mtime);
4661 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004662If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004663 atime_ns and mtime_ns should be expressed as integer nanoseconds
4664 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004665If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004666Specifying tuples for both times and ns is an error.
4667
4668If dir_fd is not None, it should be a file descriptor open to a directory,
4669 and path should be relative; path will then be relative to that directory.
4670If follow_symlinks is False, and the last element of the path is a symbolic
4671 link, utime will modify the symbolic link itself instead of the file the
4672 link points to.
4673It is an error to use dir_fd or follow_symlinks when specifying path
4674 as an open file descriptor.
4675dir_fd and follow_symlinks may not be available on your platform.
4676 If they are unavailable, using them will raise a NotImplementedError.
4677
4678[clinic start generated code]*/
4679
Larry Hastings2f936352014-08-05 14:04:04 +10004680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004681os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4682 int dir_fd, int follow_symlinks)
4683/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004684{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685#ifdef MS_WINDOWS
4686 HANDLE hFile;
4687 FILETIME atime, mtime;
4688#else
4689 int result;
4690#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004691
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004693 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004694
Christian Heimesb3c87242013-08-01 00:08:16 +02004695 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004696
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 if (times && (times != Py_None) && ns) {
4698 PyErr_SetString(PyExc_ValueError,
4699 "utime: you may specify either 'times'"
4700 " or 'ns' but not both");
4701 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004702 }
4703
4704 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004705 time_t a_sec, m_sec;
4706 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004707 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 PyErr_SetString(PyExc_TypeError,
4709 "utime: 'times' must be either"
4710 " a tuple of two ints or None");
4711 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004712 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004714 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004715 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004716 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004717 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004719 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004720 utime.atime_s = a_sec;
4721 utime.atime_ns = a_nsec;
4722 utime.mtime_s = m_sec;
4723 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004724 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004726 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 PyErr_SetString(PyExc_TypeError,
4728 "utime: 'ns' must be a tuple of two ints");
4729 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004730 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004732 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004734 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 &utime.mtime_s, &utime.mtime_ns)) {
4736 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004737 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 }
4739 else {
4740 /* times and ns are both None/unspecified. use "now". */
4741 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004742 }
4743
Victor Stinner4552ced2015-09-21 22:37:15 +02004744#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 if (follow_symlinks_specified("utime", follow_symlinks))
4746 goto exit;
4747#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004748
Larry Hastings2f936352014-08-05 14:04:04 +10004749 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4750 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4751 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004753
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754#if !defined(HAVE_UTIMENSAT)
4755 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004756 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 "utime: cannot use dir_fd and follow_symlinks "
4758 "together on this platform");
4759 goto exit;
4760 }
4761#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004762
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004763#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004765 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4766 NULL, OPEN_EXISTING,
4767 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 Py_END_ALLOW_THREADS
4769 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004770 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004772 }
4773
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004775 GetSystemTimeAsFileTime(&mtime);
4776 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004777 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004779 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4780 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 }
4782 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4783 /* Avoid putting the file name into the error here,
4784 as that may confuse the user into believing that
4785 something is wrong with the file, when it also
4786 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004787 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004789 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004790#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004792
Victor Stinner4552ced2015-09-21 22:37:15 +02004793#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004795 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004796 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004797#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798
Victor Stinner528a9ab2015-09-03 21:30:26 +02004799#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004801 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802 else
4803#endif
4804
Victor Stinner528a9ab2015-09-03 21:30:26 +02004805#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004806 if (path->fd != -1)
4807 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808 else
4809#endif
4810
Larry Hastings2f936352014-08-05 14:04:04 +10004811 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812
4813 Py_END_ALLOW_THREADS
4814
4815 if (result < 0) {
4816 /* see previous comment about not putting filename in error here */
4817 return_value = posix_error();
4818 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004820
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004821#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004822
4823 Py_INCREF(Py_None);
4824 return_value = Py_None;
4825
4826exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827#ifdef MS_WINDOWS
4828 if (hFile != INVALID_HANDLE_VALUE)
4829 CloseHandle(hFile);
4830#endif
4831 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004832}
4833
Guido van Rossum3b066191991-06-04 19:40:25 +00004834/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004835
Larry Hastings2f936352014-08-05 14:04:04 +10004836
4837/*[clinic input]
4838os._exit
4839
4840 status: int
4841
4842Exit to the system with specified status, without normal exit processing.
4843[clinic start generated code]*/
4844
Larry Hastings2f936352014-08-05 14:04:04 +10004845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004846os__exit_impl(PyObject *module, int status)
4847/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004848{
4849 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004850 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004851}
4852
Steve Dowercc16be82016-09-08 10:35:16 -07004853#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4854#define EXECV_CHAR wchar_t
4855#else
4856#define EXECV_CHAR char
4857#endif
4858
Martin v. Löwis114619e2002-10-07 06:44:21 +00004859#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4860static void
Steve Dowercc16be82016-09-08 10:35:16 -07004861free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004862{
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 Py_ssize_t i;
4864 for (i = 0; i < count; i++)
4865 PyMem_Free(array[i]);
4866 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004867}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004868
Berker Peksag81816462016-09-15 20:19:47 +03004869static int
4870fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004871{
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004873 PyObject *ub;
4874 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004875#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004876 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004877 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004878 *out = PyUnicode_AsWideCharString(ub, &size);
4879 if (*out)
4880 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004881#else
Berker Peksag81816462016-09-15 20:19:47 +03004882 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004883 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004884 size = PyBytes_GET_SIZE(ub);
4885 *out = PyMem_Malloc(size + 1);
4886 if (*out) {
4887 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4888 result = 1;
4889 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004890 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004891#endif
Berker Peksag81816462016-09-15 20:19:47 +03004892 Py_DECREF(ub);
4893 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004894}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004895#endif
4896
Ross Lagerwall7807c352011-03-17 20:20:30 +02004897#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004898static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004899parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4900{
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 Py_ssize_t i, pos, envc;
4902 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004903 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004904 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004905
Victor Stinner8c62be82010-05-06 00:08:46 +00004906 i = PyMapping_Size(env);
4907 if (i < 0)
4908 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004909 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004910 if (envlist == NULL) {
4911 PyErr_NoMemory();
4912 return NULL;
4913 }
4914 envc = 0;
4915 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004916 if (!keys)
4917 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004919 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 goto error;
4921 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4922 PyErr_Format(PyExc_TypeError,
4923 "env.keys() or env.values() is not a list");
4924 goto error;
4925 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004926
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 for (pos = 0; pos < i; pos++) {
4928 key = PyList_GetItem(keys, pos);
4929 val = PyList_GetItem(vals, pos);
4930 if (!key || !val)
4931 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004932
Berker Peksag81816462016-09-15 20:19:47 +03004933#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4934 if (!PyUnicode_FSDecoder(key, &key2))
4935 goto error;
4936 if (!PyUnicode_FSDecoder(val, &val2)) {
4937 Py_DECREF(key2);
4938 goto error;
4939 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004940 /* Search from index 1 because on Windows starting '=' is allowed for
4941 defining hidden environment variables. */
4942 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4943 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
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 = PyUnicode_FromFormat("%U=%U", key2, val2);
4951#else
4952 if (!PyUnicode_FSConverter(key, &key2))
4953 goto error;
4954 if (!PyUnicode_FSConverter(val, &val2)) {
4955 Py_DECREF(key2);
4956 goto error;
4957 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004958 if (PyBytes_GET_SIZE(key2) == 0 ||
4959 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4960 {
4961 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004962 Py_DECREF(key2);
4963 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004964 goto error;
4965 }
Berker Peksag81816462016-09-15 20:19:47 +03004966 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4967 PyBytes_AS_STRING(val2));
4968#endif
4969 Py_DECREF(key2);
4970 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004971 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004973
4974 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4975 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004976 goto error;
4977 }
Berker Peksag81816462016-09-15 20:19:47 +03004978
Steve Dowercc16be82016-09-08 10:35:16 -07004979 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 }
4981 Py_DECREF(vals);
4982 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004983
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 envlist[envc] = 0;
4985 *envc_ptr = envc;
4986 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004987
4988error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 Py_XDECREF(keys);
4990 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004991 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004993}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004994
Steve Dowercc16be82016-09-08 10:35:16 -07004995static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004996parse_arglist(PyObject* argv, Py_ssize_t *argc)
4997{
4998 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004999 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005000 if (argvlist == NULL) {
5001 PyErr_NoMemory();
5002 return NULL;
5003 }
5004 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005005 PyObject* item = PySequence_ITEM(argv, i);
5006 if (item == NULL)
5007 goto fail;
5008 if (!fsconvert_strdup(item, &argvlist[i])) {
5009 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005010 goto fail;
5011 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005012 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013 }
5014 argvlist[*argc] = NULL;
5015 return argvlist;
5016fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005017 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 free_string_array(argvlist, *argc);
5019 return NULL;
5020}
Steve Dowercc16be82016-09-08 10:35:16 -07005021
Ross Lagerwall7807c352011-03-17 20:20:30 +02005022#endif
5023
Larry Hastings2f936352014-08-05 14:04:04 +10005024
Ross Lagerwall7807c352011-03-17 20:20:30 +02005025#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005026/*[clinic input]
5027os.execv
5028
Steve Dowercc16be82016-09-08 10:35:16 -07005029 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005030 Path of executable file.
5031 argv: object
5032 Tuple or list of strings.
5033 /
5034
5035Execute an executable path with arguments, replacing current process.
5036[clinic start generated code]*/
5037
Larry Hastings2f936352014-08-05 14:04:04 +10005038static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005039os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5040/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005041{
Steve Dowercc16be82016-09-08 10:35:16 -07005042 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043 Py_ssize_t argc;
5044
5045 /* execv has two arguments: (path, argv), where
5046 argv is a list or tuple of strings. */
5047
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5049 PyErr_SetString(PyExc_TypeError,
5050 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005051 return NULL;
5052 }
5053 argc = PySequence_Size(argv);
5054 if (argc < 1) {
5055 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056 return NULL;
5057 }
5058
5059 argvlist = parse_arglist(argv, &argc);
5060 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 return NULL;
5062 }
Steve Dowerbce26262016-11-19 19:17:26 -08005063 if (!argvlist[0][0]) {
5064 PyErr_SetString(PyExc_ValueError,
5065 "execv() arg 2 first element cannot be empty");
5066 free_string_array(argvlist, argc);
5067 return NULL;
5068 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005069
Steve Dowerbce26262016-11-19 19:17:26 -08005070 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005071#ifdef HAVE_WEXECV
5072 _wexecv(path->wide, argvlist);
5073#else
5074 execv(path->narrow, argvlist);
5075#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005076 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005077
5078 /* If we get here it's definitely an error */
5079
5080 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005081 return posix_error();
5082}
5083
Larry Hastings2f936352014-08-05 14:04:04 +10005084
5085/*[clinic input]
5086os.execve
5087
5088 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5089 Path of executable file.
5090 argv: object
5091 Tuple or list of strings.
5092 env: object
5093 Dictionary of strings mapping to strings.
5094
5095Execute an executable path with arguments, replacing current process.
5096[clinic start generated code]*/
5097
Larry Hastings2f936352014-08-05 14:04:04 +10005098static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005099os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5100/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005101{
Steve Dowercc16be82016-09-08 10:35:16 -07005102 EXECV_CHAR **argvlist = NULL;
5103 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005104 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005105
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 /* execve has three arguments: (path, argv, env), where
5107 argv is a list or tuple of strings and env is a dictionary
5108 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005109
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005112 "execve: argv must be a tuple or list");
5113 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005116 if (argc < 1) {
5117 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5118 return NULL;
5119 }
5120
Victor Stinner8c62be82010-05-06 00:08:46 +00005121 if (!PyMapping_Check(env)) {
5122 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005123 "execve: environment must be a mapping object");
5124 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005125 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005126
Ross Lagerwall7807c352011-03-17 20:20:30 +02005127 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005129 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 }
Steve Dowerbce26262016-11-19 19:17:26 -08005131 if (!argvlist[0][0]) {
5132 PyErr_SetString(PyExc_ValueError,
5133 "execve: argv first element cannot be empty");
5134 goto fail;
5135 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005136
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 envlist = parse_envlist(env, &envc);
5138 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005139 goto fail;
5140
Steve Dowerbce26262016-11-19 19:17:26 -08005141 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005142#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005143 if (path->fd > -1)
5144 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005145 else
5146#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005147#ifdef HAVE_WEXECV
5148 _wexecve(path->wide, argvlist, envlist);
5149#else
Larry Hastings2f936352014-08-05 14:04:04 +10005150 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005151#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005152 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005153
5154 /* If we get here it's definitely an error */
5155
Alexey Izbyshev83460312018-10-20 03:28:22 +03005156 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005157
Steve Dowercc16be82016-09-08 10:35:16 -07005158 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005159 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005160 if (argvlist)
5161 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005162 return NULL;
5163}
Steve Dowercc16be82016-09-08 10:35:16 -07005164
Larry Hastings9cf065c2012-06-22 16:30:09 -07005165#endif /* HAVE_EXECV */
5166
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005167#ifdef HAVE_POSIX_SPAWN
5168
5169enum posix_spawn_file_actions_identifier {
5170 POSIX_SPAWN_OPEN,
5171 POSIX_SPAWN_CLOSE,
5172 POSIX_SPAWN_DUP2
5173};
5174
William Orr81574b82018-10-01 22:19:56 -07005175#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005176static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005177convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005178#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005179
5180static int
5181parse_posix_spawn_flags(PyObject *setpgroup, int resetids, PyObject *setsigmask,
5182 PyObject *setsigdef, PyObject *scheduler,
5183 posix_spawnattr_t *attrp)
5184{
5185 long all_flags = 0;
5186
5187 errno = posix_spawnattr_init(attrp);
5188 if (errno) {
5189 posix_error();
5190 return -1;
5191 }
5192
5193 if (setpgroup) {
5194 pid_t pgid = PyLong_AsPid(setpgroup);
5195 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5196 goto fail;
5197 }
5198 errno = posix_spawnattr_setpgroup(attrp, pgid);
5199 if (errno) {
5200 posix_error();
5201 goto fail;
5202 }
5203 all_flags |= POSIX_SPAWN_SETPGROUP;
5204 }
5205
5206 if (resetids) {
5207 all_flags |= POSIX_SPAWN_RESETIDS;
5208 }
5209
5210 if (setsigmask) {
5211 sigset_t set;
5212 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5213 goto fail;
5214 }
5215 errno = posix_spawnattr_setsigmask(attrp, &set);
5216 if (errno) {
5217 posix_error();
5218 goto fail;
5219 }
5220 all_flags |= POSIX_SPAWN_SETSIGMASK;
5221 }
5222
5223 if (setsigdef) {
5224 sigset_t set;
5225 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5226 goto fail;
5227 }
5228 errno = posix_spawnattr_setsigdefault(attrp, &set);
5229 if (errno) {
5230 posix_error();
5231 goto fail;
5232 }
5233 all_flags |= POSIX_SPAWN_SETSIGDEF;
5234 }
5235
5236 if (scheduler) {
5237#ifdef POSIX_SPAWN_SETSCHEDULER
5238 PyObject *py_schedpolicy;
5239 struct sched_param schedparam;
5240
5241 if (!PyArg_ParseTuple(scheduler, "OO&"
5242 ";A scheduler tuple must have two elements",
5243 &py_schedpolicy, convert_sched_param, &schedparam)) {
5244 goto fail;
5245 }
5246 if (py_schedpolicy != Py_None) {
5247 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5248
5249 if (schedpolicy == -1 && PyErr_Occurred()) {
5250 goto fail;
5251 }
5252 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5253 if (errno) {
5254 posix_error();
5255 goto fail;
5256 }
5257 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5258 }
5259 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5260 if (errno) {
5261 posix_error();
5262 goto fail;
5263 }
5264 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5265#else
5266 PyErr_SetString(PyExc_NotImplementedError,
5267 "The scheduler option is not supported in this system.");
5268 goto fail;
5269#endif
5270 }
5271
5272 errno = posix_spawnattr_setflags(attrp, all_flags);
5273 if (errno) {
5274 posix_error();
5275 goto fail;
5276 }
5277
5278 return 0;
5279
5280fail:
5281 (void)posix_spawnattr_destroy(attrp);
5282 return -1;
5283}
5284
5285static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005286parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005287 posix_spawn_file_actions_t *file_actionsp,
5288 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005289{
5290 PyObject *seq;
5291 PyObject *file_action = NULL;
5292 PyObject *tag_obj;
5293
5294 seq = PySequence_Fast(file_actions,
5295 "file_actions must be a sequence or None");
5296 if (seq == NULL) {
5297 return -1;
5298 }
5299
5300 errno = posix_spawn_file_actions_init(file_actionsp);
5301 if (errno) {
5302 posix_error();
5303 Py_DECREF(seq);
5304 return -1;
5305 }
5306
5307 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5308 file_action = PySequence_Fast_GET_ITEM(seq, i);
5309 Py_INCREF(file_action);
5310 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5311 PyErr_SetString(PyExc_TypeError,
5312 "Each file_actions element must be a non-empty tuple");
5313 goto fail;
5314 }
5315 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5316 if (tag == -1 && PyErr_Occurred()) {
5317 goto fail;
5318 }
5319
5320 /* Populate the file_actions object */
5321 switch (tag) {
5322 case POSIX_SPAWN_OPEN: {
5323 int fd, oflag;
5324 PyObject *path;
5325 unsigned long mode;
5326 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5327 ";A open file_action tuple must have 5 elements",
5328 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5329 &oflag, &mode))
5330 {
5331 goto fail;
5332 }
Pablo Galindocb970732018-06-19 09:19:50 +01005333 if (PyList_Append(temp_buffer, path)) {
5334 Py_DECREF(path);
5335 goto fail;
5336 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005337 errno = posix_spawn_file_actions_addopen(file_actionsp,
5338 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005339 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005340 if (errno) {
5341 posix_error();
5342 goto fail;
5343 }
5344 break;
5345 }
5346 case POSIX_SPAWN_CLOSE: {
5347 int fd;
5348 if (!PyArg_ParseTuple(file_action, "Oi"
5349 ";A close file_action tuple must have 2 elements",
5350 &tag_obj, &fd))
5351 {
5352 goto fail;
5353 }
5354 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5355 if (errno) {
5356 posix_error();
5357 goto fail;
5358 }
5359 break;
5360 }
5361 case POSIX_SPAWN_DUP2: {
5362 int fd1, fd2;
5363 if (!PyArg_ParseTuple(file_action, "Oii"
5364 ";A dup2 file_action tuple must have 3 elements",
5365 &tag_obj, &fd1, &fd2))
5366 {
5367 goto fail;
5368 }
5369 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5370 fd1, fd2);
5371 if (errno) {
5372 posix_error();
5373 goto fail;
5374 }
5375 break;
5376 }
5377 default: {
5378 PyErr_SetString(PyExc_TypeError,
5379 "Unknown file_actions identifier");
5380 goto fail;
5381 }
5382 }
5383 Py_DECREF(file_action);
5384 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005385
Serhiy Storchakaef347532018-05-01 16:45:04 +03005386 Py_DECREF(seq);
5387 return 0;
5388
5389fail:
5390 Py_DECREF(seq);
5391 Py_DECREF(file_action);
5392 (void)posix_spawn_file_actions_destroy(file_actionsp);
5393 return -1;
5394}
5395
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005396/*[clinic input]
5397
5398os.posix_spawn
5399 path: path_t
5400 Path of executable file.
5401 argv: object
5402 Tuple or list of strings.
5403 env: object
5404 Dictionary of strings mapping to strings.
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005405 /
Pablo Galindo254a4662018-09-07 16:44:24 +01005406 *
Serhiy Storchakad700f972018-09-08 14:48:18 +03005407 file_actions: object(c_default='NULL') = ()
5408 A sequence of file action tuples.
Pablo Galindo254a4662018-09-07 16:44:24 +01005409 setpgroup: object = NULL
5410 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5411 resetids: bool(accept={int}) = False
5412 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
5413 setsigmask: object(c_default='NULL') = ()
5414 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5415 setsigdef: object(c_default='NULL') = ()
5416 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5417 scheduler: object = NULL
5418 A tuple with the scheduler policy (optional) and parameters.
Serhiy Storchakad700f972018-09-08 14:48:18 +03005419
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005420Execute the program specified by path in a new process.
5421[clinic start generated code]*/
5422
5423static PyObject *
5424os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
Pablo Galindo254a4662018-09-07 16:44:24 +01005425 PyObject *env, PyObject *file_actions,
5426 PyObject *setpgroup, int resetids, PyObject *setsigmask,
5427 PyObject *setsigdef, PyObject *scheduler)
Serhiy Storchakad700f972018-09-08 14:48:18 +03005428/*[clinic end generated code: output=45dfa4c515d09f2c input=2891c2f1d457e39b]*/
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005429{
5430 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005431 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005432 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005433 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005434 posix_spawnattr_t attr;
5435 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005436 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005437 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005438 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005439 pid_t pid;
5440 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005441
5442 /* posix_spawn has three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005443 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005444 like posix.environ. */
5445
Serhiy Storchakaef347532018-05-01 16:45:04 +03005446 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005447 PyErr_SetString(PyExc_TypeError,
5448 "posix_spawn: argv must be a tuple or list");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005449 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005450 }
5451 argc = PySequence_Size(argv);
5452 if (argc < 1) {
5453 PyErr_SetString(PyExc_ValueError, "posix_spawn: argv must not be empty");
5454 return NULL;
5455 }
5456
5457 if (!PyMapping_Check(env)) {
5458 PyErr_SetString(PyExc_TypeError,
5459 "posix_spawn: environment must be a mapping object");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005460 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005461 }
5462
5463 argvlist = parse_arglist(argv, &argc);
5464 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005465 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005466 }
5467 if (!argvlist[0][0]) {
5468 PyErr_SetString(PyExc_ValueError,
5469 "posix_spawn: argv first element cannot be empty");
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005470 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005471 }
5472
5473 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005474 if (envlist == NULL) {
5475 goto exit;
5476 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005477
Serhiy Storchakad700f972018-09-08 14:48:18 +03005478 if (file_actions != NULL) {
Pablo Galindocb970732018-06-19 09:19:50 +01005479 /* There is a bug in old versions of glibc that makes some of the
5480 * helper functions for manipulating file actions not copy the provided
5481 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5482 * copy the value of path for some old versions of glibc (<2.20).
5483 * The use of temp_buffer here is a workaround that keeps the
5484 * python objects that own the buffers alive until posix_spawn gets called.
5485 * Check https://bugs.python.org/issue33630 and
5486 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5487 temp_buffer = PyList_New(0);
5488 if (!temp_buffer) {
5489 goto exit;
5490 }
5491 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005492 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005493 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005494 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005495 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005496
Pablo Galindo254a4662018-09-07 16:44:24 +01005497 if (parse_posix_spawn_flags(setpgroup, resetids, setsigmask,
5498 setsigdef, scheduler, &attr)) {
5499 goto exit;
5500 }
5501 attrp = &attr;
5502
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005503 _Py_BEGIN_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005504 err_code = posix_spawn(&pid, path->narrow,
Pablo Galindo254a4662018-09-07 16:44:24 +01005505 file_actionsp, attrp, argvlist, envlist);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005506 _Py_END_SUPPRESS_IPH
Serhiy Storchakaef347532018-05-01 16:45:04 +03005507 if (err_code) {
5508 errno = err_code;
5509 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005510 goto exit;
5511 }
5512 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005513
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005514exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005515 if (file_actionsp) {
5516 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005517 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005518 if (attrp) {
5519 (void)posix_spawnattr_destroy(attrp);
5520 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005521 if (envlist) {
5522 free_string_array(envlist, envc);
5523 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005524 if (argvlist) {
5525 free_string_array(argvlist, argc);
5526 }
Pablo Galindocb970732018-06-19 09:19:50 +01005527 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005528 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005529}
5530#endif /* HAVE_POSIX_SPAWN */
5531
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005532
Steve Dowercc16be82016-09-08 10:35:16 -07005533#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005534/*[clinic input]
5535os.spawnv
5536
5537 mode: int
5538 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005539 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005540 Path of executable file.
5541 argv: object
5542 Tuple or list of strings.
5543 /
5544
5545Execute the program specified by path in a new process.
5546[clinic start generated code]*/
5547
Larry Hastings2f936352014-08-05 14:04:04 +10005548static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005549os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5550/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005551{
Steve Dowercc16be82016-09-08 10:35:16 -07005552 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005553 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005554 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005555 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005556 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005557
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 /* spawnv has three arguments: (mode, path, argv), where
5559 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005560
Victor Stinner8c62be82010-05-06 00:08:46 +00005561 if (PyList_Check(argv)) {
5562 argc = PyList_Size(argv);
5563 getitem = PyList_GetItem;
5564 }
5565 else if (PyTuple_Check(argv)) {
5566 argc = PyTuple_Size(argv);
5567 getitem = PyTuple_GetItem;
5568 }
5569 else {
5570 PyErr_SetString(PyExc_TypeError,
5571 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005572 return NULL;
5573 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005574 if (argc == 0) {
5575 PyErr_SetString(PyExc_ValueError,
5576 "spawnv() arg 2 cannot be empty");
5577 return NULL;
5578 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005579
Steve Dowercc16be82016-09-08 10:35:16 -07005580 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005581 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 return PyErr_NoMemory();
5583 }
5584 for (i = 0; i < argc; i++) {
5585 if (!fsconvert_strdup((*getitem)(argv, i),
5586 &argvlist[i])) {
5587 free_string_array(argvlist, i);
5588 PyErr_SetString(
5589 PyExc_TypeError,
5590 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005591 return NULL;
5592 }
Steve Dower93ff8722016-11-19 19:03:54 -08005593 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005594 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005595 PyErr_SetString(
5596 PyExc_ValueError,
5597 "spawnv() arg 2 first element cannot be empty");
5598 return NULL;
5599 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 }
5601 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005602
Victor Stinner8c62be82010-05-06 00:08:46 +00005603 if (mode == _OLD_P_OVERLAY)
5604 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005605
Victor Stinner8c62be82010-05-06 00:08:46 +00005606 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005607 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005608#ifdef HAVE_WSPAWNV
5609 spawnval = _wspawnv(mode, path->wide, argvlist);
5610#else
5611 spawnval = _spawnv(mode, path->narrow, argvlist);
5612#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005613 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005614 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005615
Victor Stinner8c62be82010-05-06 00:08:46 +00005616 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005617
Victor Stinner8c62be82010-05-06 00:08:46 +00005618 if (spawnval == -1)
5619 return posix_error();
5620 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005621 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005622}
5623
Larry Hastings2f936352014-08-05 14:04:04 +10005624/*[clinic input]
5625os.spawnve
5626
5627 mode: int
5628 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005629 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005630 Path of executable file.
5631 argv: object
5632 Tuple or list of strings.
5633 env: object
5634 Dictionary of strings mapping to strings.
5635 /
5636
5637Execute the program specified by path in a new process.
5638[clinic start generated code]*/
5639
Larry Hastings2f936352014-08-05 14:04:04 +10005640static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005641os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005642 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005643/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005644{
Steve Dowercc16be82016-09-08 10:35:16 -07005645 EXECV_CHAR **argvlist;
5646 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005647 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005648 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005649 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005650 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005651 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005652
Victor Stinner8c62be82010-05-06 00:08:46 +00005653 /* spawnve has four arguments: (mode, path, argv, env), where
5654 argv is a list or tuple of strings and env is a dictionary
5655 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005656
Victor Stinner8c62be82010-05-06 00:08:46 +00005657 if (PyList_Check(argv)) {
5658 argc = PyList_Size(argv);
5659 getitem = PyList_GetItem;
5660 }
5661 else if (PyTuple_Check(argv)) {
5662 argc = PyTuple_Size(argv);
5663 getitem = PyTuple_GetItem;
5664 }
5665 else {
5666 PyErr_SetString(PyExc_TypeError,
5667 "spawnve() arg 2 must be a tuple or list");
5668 goto fail_0;
5669 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005670 if (argc == 0) {
5671 PyErr_SetString(PyExc_ValueError,
5672 "spawnve() arg 2 cannot be empty");
5673 goto fail_0;
5674 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 if (!PyMapping_Check(env)) {
5676 PyErr_SetString(PyExc_TypeError,
5677 "spawnve() arg 3 must be a mapping object");
5678 goto fail_0;
5679 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005680
Steve Dowercc16be82016-09-08 10:35:16 -07005681 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005682 if (argvlist == NULL) {
5683 PyErr_NoMemory();
5684 goto fail_0;
5685 }
5686 for (i = 0; i < argc; i++) {
5687 if (!fsconvert_strdup((*getitem)(argv, i),
5688 &argvlist[i]))
5689 {
5690 lastarg = i;
5691 goto fail_1;
5692 }
Steve Dowerbce26262016-11-19 19:17:26 -08005693 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005694 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005695 PyErr_SetString(
5696 PyExc_ValueError,
5697 "spawnv() arg 2 first element cannot be empty");
5698 goto fail_1;
5699 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005700 }
5701 lastarg = argc;
5702 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005703
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 envlist = parse_envlist(env, &envc);
5705 if (envlist == NULL)
5706 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005707
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 if (mode == _OLD_P_OVERLAY)
5709 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005710
Victor Stinner8c62be82010-05-06 00:08:46 +00005711 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005712 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005713#ifdef HAVE_WSPAWNV
5714 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5715#else
5716 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5717#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005718 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005719 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005720
Victor Stinner8c62be82010-05-06 00:08:46 +00005721 if (spawnval == -1)
5722 (void) posix_error();
5723 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005724 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005725
Victor Stinner8c62be82010-05-06 00:08:46 +00005726 while (--envc >= 0)
5727 PyMem_DEL(envlist[envc]);
5728 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005729 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005730 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005731 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005732 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005733}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005734
Guido van Rossuma1065681999-01-25 23:20:23 +00005735#endif /* HAVE_SPAWNV */
5736
5737
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005738#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005739
5740/* Helper function to validate arguments.
5741 Returns 0 on success. non-zero on failure with a TypeError raised.
5742 If obj is non-NULL it must be callable. */
5743static int
5744check_null_or_callable(PyObject *obj, const char* obj_name)
5745{
5746 if (obj && !PyCallable_Check(obj)) {
5747 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5748 obj_name, Py_TYPE(obj)->tp_name);
5749 return -1;
5750 }
5751 return 0;
5752}
5753
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005754/*[clinic input]
5755os.register_at_fork
5756
Gregory P. Smith163468a2017-05-29 10:03:41 -07005757 *
5758 before: object=NULL
5759 A callable to be called in the parent before the fork() syscall.
5760 after_in_child: object=NULL
5761 A callable to be called in the child after fork().
5762 after_in_parent: object=NULL
5763 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005764
Gregory P. Smith163468a2017-05-29 10:03:41 -07005765Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005766
Gregory P. Smith163468a2017-05-29 10:03:41 -07005767'before' callbacks are called in reverse order.
5768'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005769
5770[clinic start generated code]*/
5771
5772static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005773os_register_at_fork_impl(PyObject *module, PyObject *before,
5774 PyObject *after_in_child, PyObject *after_in_parent)
5775/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005776{
5777 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005778
Gregory P. Smith163468a2017-05-29 10:03:41 -07005779 if (!before && !after_in_child && !after_in_parent) {
5780 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5781 return NULL;
5782 }
5783 if (check_null_or_callable(before, "before") ||
5784 check_null_or_callable(after_in_child, "after_in_child") ||
5785 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005786 return NULL;
5787 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005788 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005789
Gregory P. Smith163468a2017-05-29 10:03:41 -07005790 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005791 return NULL;
5792 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005793 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005794 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005795 }
5796 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5797 return NULL;
5798 }
5799 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005800}
5801#endif /* HAVE_FORK */
5802
5803
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005804#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005805/*[clinic input]
5806os.fork1
5807
5808Fork a child process with a single multiplexed (i.e., not bound) thread.
5809
5810Return 0 to child process and PID of child to parent process.
5811[clinic start generated code]*/
5812
Larry Hastings2f936352014-08-05 14:04:04 +10005813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005814os_fork1_impl(PyObject *module)
5815/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005816{
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005818
Eric Snow59032962018-09-14 14:17:20 -07005819 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5820 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5821 return NULL;
5822 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005823 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005824 pid = fork1();
5825 if (pid == 0) {
5826 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005827 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 } else {
5829 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005830 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 }
5832 if (pid == -1)
5833 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005834 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005835}
Larry Hastings2f936352014-08-05 14:04:04 +10005836#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005837
5838
Guido van Rossumad0ee831995-03-01 10:34:45 +00005839#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005840/*[clinic input]
5841os.fork
5842
5843Fork a child process.
5844
5845Return 0 to child process and PID of child to parent process.
5846[clinic start generated code]*/
5847
Larry Hastings2f936352014-08-05 14:04:04 +10005848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005849os_fork_impl(PyObject *module)
5850/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005851{
Victor Stinner8c62be82010-05-06 00:08:46 +00005852 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005853
Eric Snow59032962018-09-14 14:17:20 -07005854 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5855 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5856 return NULL;
5857 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005858 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005859 pid = fork();
5860 if (pid == 0) {
5861 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005862 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005863 } else {
5864 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005865 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005866 }
5867 if (pid == -1)
5868 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005870}
Larry Hastings2f936352014-08-05 14:04:04 +10005871#endif /* HAVE_FORK */
5872
Guido van Rossum85e3b011991-06-03 12:42:10 +00005873
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005874#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005875#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005876/*[clinic input]
5877os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005878
Larry Hastings2f936352014-08-05 14:04:04 +10005879 policy: int
5880
5881Get the maximum scheduling priority for policy.
5882[clinic start generated code]*/
5883
Larry Hastings2f936352014-08-05 14:04:04 +10005884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005885os_sched_get_priority_max_impl(PyObject *module, int policy)
5886/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005887{
5888 int max;
5889
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005890 max = sched_get_priority_max(policy);
5891 if (max < 0)
5892 return posix_error();
5893 return PyLong_FromLong(max);
5894}
5895
Larry Hastings2f936352014-08-05 14:04:04 +10005896
5897/*[clinic input]
5898os.sched_get_priority_min
5899
5900 policy: int
5901
5902Get the minimum scheduling priority for policy.
5903[clinic start generated code]*/
5904
Larry Hastings2f936352014-08-05 14:04:04 +10005905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005906os_sched_get_priority_min_impl(PyObject *module, int policy)
5907/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005908{
5909 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005910 if (min < 0)
5911 return posix_error();
5912 return PyLong_FromLong(min);
5913}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005914#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5915
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005916
Larry Hastings2f936352014-08-05 14:04:04 +10005917#ifdef HAVE_SCHED_SETSCHEDULER
5918/*[clinic input]
5919os.sched_getscheduler
5920 pid: pid_t
5921 /
5922
5923Get the scheduling policy for the process identifiedy by pid.
5924
5925Passing 0 for pid returns the scheduling policy for the calling process.
5926[clinic start generated code]*/
5927
Larry Hastings2f936352014-08-05 14:04:04 +10005928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005929os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5930/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005931{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005932 int policy;
5933
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005934 policy = sched_getscheduler(pid);
5935 if (policy < 0)
5936 return posix_error();
5937 return PyLong_FromLong(policy);
5938}
Larry Hastings2f936352014-08-05 14:04:04 +10005939#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005940
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005941
William Orr81574b82018-10-01 22:19:56 -07005942#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005943/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005944class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10005945
5946@classmethod
5947os.sched_param.__new__
5948
5949 sched_priority: object
5950 A scheduling parameter.
5951
5952Current has only one field: sched_priority");
5953[clinic start generated code]*/
5954
Larry Hastings2f936352014-08-05 14:04:04 +10005955static PyObject *
5956os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005957/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005958{
5959 PyObject *res;
5960
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005961 res = PyStructSequence_New(type);
5962 if (!res)
5963 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005964 Py_INCREF(sched_priority);
5965 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005966 return res;
5967}
5968
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005969
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005970PyDoc_VAR(os_sched_param__doc__);
5971
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005972static PyStructSequence_Field sched_param_fields[] = {
5973 {"sched_priority", "the scheduling priority"},
5974 {0}
5975};
5976
5977static PyStructSequence_Desc sched_param_desc = {
5978 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005979 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005980 sched_param_fields,
5981 1
5982};
5983
5984static int
5985convert_sched_param(PyObject *param, struct sched_param *res)
5986{
5987 long priority;
5988
Eddie Elizondo474eedf2018-11-13 04:09:31 -08005989 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005990 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5991 return 0;
5992 }
5993 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5994 if (priority == -1 && PyErr_Occurred())
5995 return 0;
5996 if (priority > INT_MAX || priority < INT_MIN) {
5997 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5998 return 0;
5999 }
6000 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6001 return 1;
6002}
William Orr81574b82018-10-01 22:19:56 -07006003#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006004
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006005
6006#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006007/*[clinic input]
6008os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006009
Larry Hastings2f936352014-08-05 14:04:04 +10006010 pid: pid_t
6011 policy: int
6012 param: sched_param
6013 /
6014
6015Set the scheduling policy for the process identified by pid.
6016
6017If pid is 0, the calling process is changed.
6018param is an instance of sched_param.
6019[clinic start generated code]*/
6020
Larry Hastings2f936352014-08-05 14:04:04 +10006021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006022os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006023 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006024/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006025{
Jesus Cea9c822272011-09-10 01:40:52 +02006026 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006027 ** sched_setscheduler() returns 0 in Linux, but the previous
6028 ** scheduling policy under Solaris/Illumos, and others.
6029 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006030 */
Larry Hastings2f936352014-08-05 14:04:04 +10006031 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006032 return posix_error();
6033 Py_RETURN_NONE;
6034}
Larry Hastings2f936352014-08-05 14:04:04 +10006035#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006036
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006037
6038#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006039/*[clinic input]
6040os.sched_getparam
6041 pid: pid_t
6042 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006043
Larry Hastings2f936352014-08-05 14:04:04 +10006044Returns scheduling parameters for the process identified by pid.
6045
6046If pid is 0, returns parameters for the calling process.
6047Return value is an instance of sched_param.
6048[clinic start generated code]*/
6049
Larry Hastings2f936352014-08-05 14:04:04 +10006050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006051os_sched_getparam_impl(PyObject *module, pid_t pid)
6052/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006053{
6054 struct sched_param param;
6055 PyObject *result;
6056 PyObject *priority;
6057
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006058 if (sched_getparam(pid, &param))
6059 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006060 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006061 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006062 return NULL;
6063 priority = PyLong_FromLong(param.sched_priority);
6064 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006065 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006066 return NULL;
6067 }
Larry Hastings2f936352014-08-05 14:04:04 +10006068 PyStructSequence_SET_ITEM(result, 0, priority);
6069 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006070}
6071
Larry Hastings2f936352014-08-05 14:04:04 +10006072
6073/*[clinic input]
6074os.sched_setparam
6075 pid: pid_t
6076 param: sched_param
6077 /
6078
6079Set scheduling parameters for the process identified by pid.
6080
6081If pid is 0, sets parameters for the calling process.
6082param should be an instance of sched_param.
6083[clinic start generated code]*/
6084
Larry Hastings2f936352014-08-05 14:04:04 +10006085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006086os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006087 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006088/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006089{
6090 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006091 return posix_error();
6092 Py_RETURN_NONE;
6093}
Larry Hastings2f936352014-08-05 14:04:04 +10006094#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006095
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006096
6097#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006098/*[clinic input]
6099os.sched_rr_get_interval -> double
6100 pid: pid_t
6101 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006102
Larry Hastings2f936352014-08-05 14:04:04 +10006103Return the round-robin quantum for the process identified by pid, in seconds.
6104
6105Value returned is a float.
6106[clinic start generated code]*/
6107
Larry Hastings2f936352014-08-05 14:04:04 +10006108static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006109os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6110/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006111{
6112 struct timespec interval;
6113 if (sched_rr_get_interval(pid, &interval)) {
6114 posix_error();
6115 return -1.0;
6116 }
6117 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6118}
6119#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006120
Larry Hastings2f936352014-08-05 14:04:04 +10006121
6122/*[clinic input]
6123os.sched_yield
6124
6125Voluntarily relinquish the CPU.
6126[clinic start generated code]*/
6127
Larry Hastings2f936352014-08-05 14:04:04 +10006128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006129os_sched_yield_impl(PyObject *module)
6130/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006131{
6132 if (sched_yield())
6133 return posix_error();
6134 Py_RETURN_NONE;
6135}
6136
Benjamin Peterson2740af82011-08-02 17:41:34 -05006137#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006138/* The minimum number of CPUs allocated in a cpu_set_t */
6139static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006140
Larry Hastings2f936352014-08-05 14:04:04 +10006141/*[clinic input]
6142os.sched_setaffinity
6143 pid: pid_t
6144 mask : object
6145 /
6146
6147Set the CPU affinity of the process identified by pid to mask.
6148
6149mask should be an iterable of integers identifying CPUs.
6150[clinic start generated code]*/
6151
Larry Hastings2f936352014-08-05 14:04:04 +10006152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006153os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6154/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006155{
Antoine Pitrou84869872012-08-04 16:16:35 +02006156 int ncpus;
6157 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006158 cpu_set_t *cpu_set = NULL;
6159 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006160
Larry Hastings2f936352014-08-05 14:04:04 +10006161 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006162 if (iterator == NULL)
6163 return NULL;
6164
6165 ncpus = NCPUS_START;
6166 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006167 cpu_set = CPU_ALLOC(ncpus);
6168 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006169 PyErr_NoMemory();
6170 goto error;
6171 }
Larry Hastings2f936352014-08-05 14:04:04 +10006172 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006173
6174 while ((item = PyIter_Next(iterator))) {
6175 long cpu;
6176 if (!PyLong_Check(item)) {
6177 PyErr_Format(PyExc_TypeError,
6178 "expected an iterator of ints, "
6179 "but iterator yielded %R",
6180 Py_TYPE(item));
6181 Py_DECREF(item);
6182 goto error;
6183 }
6184 cpu = PyLong_AsLong(item);
6185 Py_DECREF(item);
6186 if (cpu < 0) {
6187 if (!PyErr_Occurred())
6188 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6189 goto error;
6190 }
6191 if (cpu > INT_MAX - 1) {
6192 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6193 goto error;
6194 }
6195 if (cpu >= ncpus) {
6196 /* Grow CPU mask to fit the CPU number */
6197 int newncpus = ncpus;
6198 cpu_set_t *newmask;
6199 size_t newsetsize;
6200 while (newncpus <= cpu) {
6201 if (newncpus > INT_MAX / 2)
6202 newncpus = cpu + 1;
6203 else
6204 newncpus = newncpus * 2;
6205 }
6206 newmask = CPU_ALLOC(newncpus);
6207 if (newmask == NULL) {
6208 PyErr_NoMemory();
6209 goto error;
6210 }
6211 newsetsize = CPU_ALLOC_SIZE(newncpus);
6212 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006213 memcpy(newmask, cpu_set, setsize);
6214 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006215 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006216 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006217 ncpus = newncpus;
6218 }
Larry Hastings2f936352014-08-05 14:04:04 +10006219 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006220 }
6221 Py_CLEAR(iterator);
6222
Larry Hastings2f936352014-08-05 14:04:04 +10006223 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006224 posix_error();
6225 goto error;
6226 }
Larry Hastings2f936352014-08-05 14:04:04 +10006227 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006228 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006229
6230error:
Larry Hastings2f936352014-08-05 14:04:04 +10006231 if (cpu_set)
6232 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006233 Py_XDECREF(iterator);
6234 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006235}
6236
Larry Hastings2f936352014-08-05 14:04:04 +10006237
6238/*[clinic input]
6239os.sched_getaffinity
6240 pid: pid_t
6241 /
6242
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006243Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006244
6245The affinity is returned as a set of CPU identifiers.
6246[clinic start generated code]*/
6247
Larry Hastings2f936352014-08-05 14:04:04 +10006248static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006249os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006250/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006251{
Antoine Pitrou84869872012-08-04 16:16:35 +02006252 int cpu, ncpus, count;
6253 size_t setsize;
6254 cpu_set_t *mask = NULL;
6255 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006256
Antoine Pitrou84869872012-08-04 16:16:35 +02006257 ncpus = NCPUS_START;
6258 while (1) {
6259 setsize = CPU_ALLOC_SIZE(ncpus);
6260 mask = CPU_ALLOC(ncpus);
6261 if (mask == NULL)
6262 return PyErr_NoMemory();
6263 if (sched_getaffinity(pid, setsize, mask) == 0)
6264 break;
6265 CPU_FREE(mask);
6266 if (errno != EINVAL)
6267 return posix_error();
6268 if (ncpus > INT_MAX / 2) {
6269 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6270 "a large enough CPU set");
6271 return NULL;
6272 }
6273 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006274 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006275
6276 res = PySet_New(NULL);
6277 if (res == NULL)
6278 goto error;
6279 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6280 if (CPU_ISSET_S(cpu, setsize, mask)) {
6281 PyObject *cpu_num = PyLong_FromLong(cpu);
6282 --count;
6283 if (cpu_num == NULL)
6284 goto error;
6285 if (PySet_Add(res, cpu_num)) {
6286 Py_DECREF(cpu_num);
6287 goto error;
6288 }
6289 Py_DECREF(cpu_num);
6290 }
6291 }
6292 CPU_FREE(mask);
6293 return res;
6294
6295error:
6296 if (mask)
6297 CPU_FREE(mask);
6298 Py_XDECREF(res);
6299 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006300}
6301
Benjamin Peterson2740af82011-08-02 17:41:34 -05006302#endif /* HAVE_SCHED_SETAFFINITY */
6303
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006304#endif /* HAVE_SCHED_H */
6305
Larry Hastings2f936352014-08-05 14:04:04 +10006306
Neal Norwitzb59798b2003-03-21 01:43:31 +00006307/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006308/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6309#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006310#define DEV_PTY_FILE "/dev/ptc"
6311#define HAVE_DEV_PTMX
6312#else
6313#define DEV_PTY_FILE "/dev/ptmx"
6314#endif
6315
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006316#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006317#ifdef HAVE_PTY_H
6318#include <pty.h>
6319#else
6320#ifdef HAVE_LIBUTIL_H
6321#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006322#else
6323#ifdef HAVE_UTIL_H
6324#include <util.h>
6325#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006326#endif /* HAVE_LIBUTIL_H */
6327#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006328#ifdef HAVE_STROPTS_H
6329#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006330#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006331#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006332
Larry Hastings2f936352014-08-05 14:04:04 +10006333
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006334#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006335/*[clinic input]
6336os.openpty
6337
6338Open a pseudo-terminal.
6339
6340Return a tuple of (master_fd, slave_fd) containing open file descriptors
6341for both the master and slave ends.
6342[clinic start generated code]*/
6343
Larry Hastings2f936352014-08-05 14:04:04 +10006344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006345os_openpty_impl(PyObject *module)
6346/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006347{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006348 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006349#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006350 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006351#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006352#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006354#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006356#endif
6357#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006358
Thomas Wouters70c21a12000-07-14 14:28:33 +00006359#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006360 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006361 goto posix_error;
6362
6363 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6364 goto error;
6365 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6366 goto error;
6367
Neal Norwitzb59798b2003-03-21 01:43:31 +00006368#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6370 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006371 goto posix_error;
6372 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6373 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006374
Victor Stinnerdaf45552013-08-28 00:53:59 +02006375 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006377 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006378
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006379#else
Victor Stinner000de532013-11-25 23:19:58 +01006380 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006382 goto posix_error;
6383
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006385
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 /* change permission of slave */
6387 if (grantpt(master_fd) < 0) {
6388 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006389 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006391
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 /* unlock slave */
6393 if (unlockpt(master_fd) < 0) {
6394 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006395 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006397
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006399
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 slave_name = ptsname(master_fd); /* get name of slave */
6401 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006402 goto posix_error;
6403
6404 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006405 if (slave_fd == -1)
6406 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006407
6408 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6409 goto posix_error;
6410
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006411#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006412 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6413 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006414#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006416#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006417#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006418#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006419
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006421
Victor Stinnerdaf45552013-08-28 00:53:59 +02006422posix_error:
6423 posix_error();
6424error:
6425 if (master_fd != -1)
6426 close(master_fd);
6427 if (slave_fd != -1)
6428 close(slave_fd);
6429 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006430}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006431#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006432
Larry Hastings2f936352014-08-05 14:04:04 +10006433
Fred Drake8cef4cf2000-06-28 16:40:38 +00006434#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006435/*[clinic input]
6436os.forkpty
6437
6438Fork a new process with a new pseudo-terminal as controlling tty.
6439
6440Returns a tuple of (pid, master_fd).
6441Like fork(), return pid of 0 to the child process,
6442and pid of child to the parent process.
6443To both, return fd of newly opened pseudo-terminal.
6444[clinic start generated code]*/
6445
Larry Hastings2f936352014-08-05 14:04:04 +10006446static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006447os_forkpty_impl(PyObject *module)
6448/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006449{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006450 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006452
Eric Snow59032962018-09-14 14:17:20 -07006453 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6454 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6455 return NULL;
6456 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006457 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 pid = forkpty(&master_fd, NULL, NULL, NULL);
6459 if (pid == 0) {
6460 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006461 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006462 } else {
6463 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006464 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 }
6466 if (pid == -1)
6467 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006469}
Larry Hastings2f936352014-08-05 14:04:04 +10006470#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Ross Lagerwall7807c352011-03-17 20:20:30 +02006472
Guido van Rossumad0ee831995-03-01 10:34:45 +00006473#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006474/*[clinic input]
6475os.getegid
6476
6477Return the current process's effective group id.
6478[clinic start generated code]*/
6479
Larry Hastings2f936352014-08-05 14:04:04 +10006480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006481os_getegid_impl(PyObject *module)
6482/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006483{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006484 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006485}
Larry Hastings2f936352014-08-05 14:04:04 +10006486#endif /* HAVE_GETEGID */
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_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006490/*[clinic input]
6491os.geteuid
6492
6493Return the current process's effective user id.
6494[clinic start generated code]*/
6495
Larry Hastings2f936352014-08-05 14:04:04 +10006496static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006497os_geteuid_impl(PyObject *module)
6498/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006499{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006500 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006501}
Larry Hastings2f936352014-08-05 14:04:04 +10006502#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Guido van Rossumad0ee831995-03-01 10:34:45 +00006505#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006506/*[clinic input]
6507os.getgid
6508
6509Return the current process's group id.
6510[clinic start generated code]*/
6511
Larry Hastings2f936352014-08-05 14:04:04 +10006512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006513os_getgid_impl(PyObject *module)
6514/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006515{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006516 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006517}
Larry Hastings2f936352014-08-05 14:04:04 +10006518#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006520
Berker Peksag39404992016-09-15 20:45:16 +03006521#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006522/*[clinic input]
6523os.getpid
6524
6525Return the current process id.
6526[clinic start generated code]*/
6527
Larry Hastings2f936352014-08-05 14:04:04 +10006528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006529os_getpid_impl(PyObject *module)
6530/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006531{
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006533}
Berker Peksag39404992016-09-15 20:45:16 +03006534#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006535
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006536#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006537
6538/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006539PyDoc_STRVAR(posix_getgrouplist__doc__,
6540"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6541Returns a list of groups to which a user belongs.\n\n\
6542 user: username to lookup\n\
6543 group: base group id of the user");
6544
6545static PyObject *
6546posix_getgrouplist(PyObject *self, PyObject *args)
6547{
6548#ifdef NGROUPS_MAX
6549#define MAX_GROUPS NGROUPS_MAX
6550#else
6551 /* defined to be 16 on Solaris7, so this should be a small number */
6552#define MAX_GROUPS 64
6553#endif
6554
6555 const char *user;
6556 int i, ngroups;
6557 PyObject *list;
6558#ifdef __APPLE__
6559 int *groups, basegid;
6560#else
6561 gid_t *groups, basegid;
6562#endif
6563 ngroups = MAX_GROUPS;
6564
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006565#ifdef __APPLE__
6566 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006567 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006568#else
6569 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6570 _Py_Gid_Converter, &basegid))
6571 return NULL;
6572#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006573
6574#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006575 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006576#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006577 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006578#endif
6579 if (groups == NULL)
6580 return PyErr_NoMemory();
6581
6582 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6583 PyMem_Del(groups);
6584 return posix_error();
6585 }
6586
6587 list = PyList_New(ngroups);
6588 if (list == NULL) {
6589 PyMem_Del(groups);
6590 return NULL;
6591 }
6592
6593 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006594#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006595 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006596#else
6597 PyObject *o = _PyLong_FromGid(groups[i]);
6598#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006599 if (o == NULL) {
6600 Py_DECREF(list);
6601 PyMem_Del(groups);
6602 return NULL;
6603 }
6604 PyList_SET_ITEM(list, i, o);
6605 }
6606
6607 PyMem_Del(groups);
6608
6609 return list;
6610}
Larry Hastings2f936352014-08-05 14:04:04 +10006611#endif /* HAVE_GETGROUPLIST */
6612
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006613
Fred Drakec9680921999-12-13 16:37:25 +00006614#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006615/*[clinic input]
6616os.getgroups
6617
6618Return list of supplemental group IDs for the process.
6619[clinic start generated code]*/
6620
Larry Hastings2f936352014-08-05 14:04:04 +10006621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006622os_getgroups_impl(PyObject *module)
6623/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006624{
6625 PyObject *result = NULL;
6626
Fred Drakec9680921999-12-13 16:37:25 +00006627#ifdef NGROUPS_MAX
6628#define MAX_GROUPS NGROUPS_MAX
6629#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006631#define MAX_GROUPS 64
6632#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006633 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006634
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006635 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006636 * This is a helper variable to store the intermediate result when
6637 * that happens.
6638 *
6639 * To keep the code readable the OSX behaviour is unconditional,
6640 * according to the POSIX spec this should be safe on all unix-y
6641 * systems.
6642 */
6643 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006645
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006646#ifdef __APPLE__
6647 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6648 * there are more groups than can fit in grouplist. Therefore, on OS X
6649 * always first call getgroups with length 0 to get the actual number
6650 * of groups.
6651 */
6652 n = getgroups(0, NULL);
6653 if (n < 0) {
6654 return posix_error();
6655 } else if (n <= MAX_GROUPS) {
6656 /* groups will fit in existing array */
6657 alt_grouplist = grouplist;
6658 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006659 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006660 if (alt_grouplist == NULL) {
6661 errno = EINVAL;
6662 return posix_error();
6663 }
6664 }
6665
6666 n = getgroups(n, alt_grouplist);
6667 if (n == -1) {
6668 if (alt_grouplist != grouplist) {
6669 PyMem_Free(alt_grouplist);
6670 }
6671 return posix_error();
6672 }
6673#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006675 if (n < 0) {
6676 if (errno == EINVAL) {
6677 n = getgroups(0, NULL);
6678 if (n == -1) {
6679 return posix_error();
6680 }
6681 if (n == 0) {
6682 /* Avoid malloc(0) */
6683 alt_grouplist = grouplist;
6684 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006685 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006686 if (alt_grouplist == NULL) {
6687 errno = EINVAL;
6688 return posix_error();
6689 }
6690 n = getgroups(n, alt_grouplist);
6691 if (n == -1) {
6692 PyMem_Free(alt_grouplist);
6693 return posix_error();
6694 }
6695 }
6696 } else {
6697 return posix_error();
6698 }
6699 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006700#endif
6701
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006702 result = PyList_New(n);
6703 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 int i;
6705 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006706 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006708 Py_DECREF(result);
6709 result = NULL;
6710 break;
Fred Drakec9680921999-12-13 16:37:25 +00006711 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006713 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006714 }
6715
6716 if (alt_grouplist != grouplist) {
6717 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006719
Fred Drakec9680921999-12-13 16:37:25 +00006720 return result;
6721}
Larry Hastings2f936352014-08-05 14:04:04 +10006722#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006723
Antoine Pitroub7572f02009-12-02 20:46:48 +00006724#ifdef HAVE_INITGROUPS
6725PyDoc_STRVAR(posix_initgroups__doc__,
6726"initgroups(username, gid) -> None\n\n\
6727Call the system initgroups() to initialize the group access list with all of\n\
6728the groups of which the specified username is a member, plus the specified\n\
6729group id.");
6730
Larry Hastings2f936352014-08-05 14:04:04 +10006731/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006732static PyObject *
6733posix_initgroups(PyObject *self, PyObject *args)
6734{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006735 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006736 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006737 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006738#ifdef __APPLE__
6739 int gid;
6740#else
6741 gid_t gid;
6742#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006743
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006744#ifdef __APPLE__
6745 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6746 PyUnicode_FSConverter, &oname,
6747 &gid))
6748#else
6749 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6750 PyUnicode_FSConverter, &oname,
6751 _Py_Gid_Converter, &gid))
6752#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006754 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006755
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006756 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006757 Py_DECREF(oname);
6758 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006760
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006761 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006762}
Larry Hastings2f936352014-08-05 14:04:04 +10006763#endif /* HAVE_INITGROUPS */
6764
Antoine Pitroub7572f02009-12-02 20:46:48 +00006765
Martin v. Löwis606edc12002-06-13 21:09:11 +00006766#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006767/*[clinic input]
6768os.getpgid
6769
6770 pid: pid_t
6771
6772Call the system call getpgid(), and return the result.
6773[clinic start generated code]*/
6774
Larry Hastings2f936352014-08-05 14:04:04 +10006775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006776os_getpgid_impl(PyObject *module, pid_t pid)
6777/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006778{
6779 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 if (pgid < 0)
6781 return posix_error();
6782 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006783}
6784#endif /* HAVE_GETPGID */
6785
6786
Guido van Rossumb6775db1994-08-01 11:34:53 +00006787#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006788/*[clinic input]
6789os.getpgrp
6790
6791Return the current process group id.
6792[clinic start generated code]*/
6793
Larry Hastings2f936352014-08-05 14:04:04 +10006794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006795os_getpgrp_impl(PyObject *module)
6796/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006797{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006798#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006800#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006802#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006803}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006804#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006806
Guido van Rossumb6775db1994-08-01 11:34:53 +00006807#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006808/*[clinic input]
6809os.setpgrp
6810
6811Make the current process the leader of its process group.
6812[clinic start generated code]*/
6813
Larry Hastings2f936352014-08-05 14:04:04 +10006814static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006815os_setpgrp_impl(PyObject *module)
6816/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006817{
Guido van Rossum64933891994-10-20 21:56:42 +00006818#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006820#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006822#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006824 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006825}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006826#endif /* HAVE_SETPGRP */
6827
Guido van Rossumad0ee831995-03-01 10:34:45 +00006828#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006829
6830#ifdef MS_WINDOWS
6831#include <tlhelp32.h>
6832
6833static PyObject*
6834win32_getppid()
6835{
6836 HANDLE snapshot;
6837 pid_t mypid;
6838 PyObject* result = NULL;
6839 BOOL have_record;
6840 PROCESSENTRY32 pe;
6841
6842 mypid = getpid(); /* This function never fails */
6843
6844 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6845 if (snapshot == INVALID_HANDLE_VALUE)
6846 return PyErr_SetFromWindowsErr(GetLastError());
6847
6848 pe.dwSize = sizeof(pe);
6849 have_record = Process32First(snapshot, &pe);
6850 while (have_record) {
6851 if (mypid == (pid_t)pe.th32ProcessID) {
6852 /* We could cache the ulong value in a static variable. */
6853 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6854 break;
6855 }
6856
6857 have_record = Process32Next(snapshot, &pe);
6858 }
6859
6860 /* If our loop exits and our pid was not found (result will be NULL)
6861 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6862 * error anyway, so let's raise it. */
6863 if (!result)
6864 result = PyErr_SetFromWindowsErr(GetLastError());
6865
6866 CloseHandle(snapshot);
6867
6868 return result;
6869}
6870#endif /*MS_WINDOWS*/
6871
Larry Hastings2f936352014-08-05 14:04:04 +10006872
6873/*[clinic input]
6874os.getppid
6875
6876Return the parent's process id.
6877
6878If the parent process has already exited, Windows machines will still
6879return its id; others systems will return the id of the 'init' process (1).
6880[clinic start generated code]*/
6881
Larry Hastings2f936352014-08-05 14:04:04 +10006882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006883os_getppid_impl(PyObject *module)
6884/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006885{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006886#ifdef MS_WINDOWS
6887 return win32_getppid();
6888#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006890#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006891}
6892#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006894
Fred Drake12c6e2d1999-12-14 21:25:03 +00006895#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006896/*[clinic input]
6897os.getlogin
6898
6899Return the actual login name.
6900[clinic start generated code]*/
6901
Larry Hastings2f936352014-08-05 14:04:04 +10006902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006903os_getlogin_impl(PyObject *module)
6904/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006905{
Victor Stinner8c62be82010-05-06 00:08:46 +00006906 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006907#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006908 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006909 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006910
6911 if (GetUserNameW(user_name, &num_chars)) {
6912 /* num_chars is the number of unicode chars plus null terminator */
6913 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006914 }
6915 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006916 result = PyErr_SetFromWindowsErr(GetLastError());
6917#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 char *name;
6919 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006920
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 errno = 0;
6922 name = getlogin();
6923 if (name == NULL) {
6924 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006925 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006926 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006927 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 }
6929 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006930 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006932#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006933 return result;
6934}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006935#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006936
Larry Hastings2f936352014-08-05 14:04:04 +10006937
Guido van Rossumad0ee831995-03-01 10:34:45 +00006938#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006939/*[clinic input]
6940os.getuid
6941
6942Return the current process's user id.
6943[clinic start generated code]*/
6944
Larry Hastings2f936352014-08-05 14:04:04 +10006945static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006946os_getuid_impl(PyObject *module)
6947/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006948{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006949 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006950}
Larry Hastings2f936352014-08-05 14:04:04 +10006951#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006953
Brian Curtineb24d742010-04-12 17:16:38 +00006954#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006955#define HAVE_KILL
6956#endif /* MS_WINDOWS */
6957
6958#ifdef HAVE_KILL
6959/*[clinic input]
6960os.kill
6961
6962 pid: pid_t
6963 signal: Py_ssize_t
6964 /
6965
6966Kill a process with a signal.
6967[clinic start generated code]*/
6968
Larry Hastings2f936352014-08-05 14:04:04 +10006969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006970os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6971/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006972#ifndef MS_WINDOWS
6973{
6974 if (kill(pid, (int)signal) == -1)
6975 return posix_error();
6976 Py_RETURN_NONE;
6977}
6978#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006979{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006980 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006981 DWORD sig = (DWORD)signal;
6982 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006984
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 /* Console processes which share a common console can be sent CTRL+C or
6986 CTRL+BREAK events, provided they handle said events. */
6987 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006988 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 err = GetLastError();
6990 PyErr_SetFromWindowsErr(err);
6991 }
6992 else
6993 Py_RETURN_NONE;
6994 }
Brian Curtineb24d742010-04-12 17:16:38 +00006995
Victor Stinner8c62be82010-05-06 00:08:46 +00006996 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6997 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006998 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 if (handle == NULL) {
7000 err = GetLastError();
7001 return PyErr_SetFromWindowsErr(err);
7002 }
Brian Curtineb24d742010-04-12 17:16:38 +00007003
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 if (TerminateProcess(handle, sig) == 0) {
7005 err = GetLastError();
7006 result = PyErr_SetFromWindowsErr(err);
7007 } else {
7008 Py_INCREF(Py_None);
7009 result = Py_None;
7010 }
Brian Curtineb24d742010-04-12 17:16:38 +00007011
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 CloseHandle(handle);
7013 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007014}
Larry Hastings2f936352014-08-05 14:04:04 +10007015#endif /* !MS_WINDOWS */
7016#endif /* HAVE_KILL */
7017
7018
7019#ifdef HAVE_KILLPG
7020/*[clinic input]
7021os.killpg
7022
7023 pgid: pid_t
7024 signal: int
7025 /
7026
7027Kill a process group with a signal.
7028[clinic start generated code]*/
7029
Larry Hastings2f936352014-08-05 14:04:04 +10007030static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007031os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7032/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007033{
7034 /* XXX some man pages make the `pgid` parameter an int, others
7035 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7036 take the same type. Moreover, pid_t is always at least as wide as
7037 int (else compilation of this module fails), which is safe. */
7038 if (killpg(pgid, signal) == -1)
7039 return posix_error();
7040 Py_RETURN_NONE;
7041}
7042#endif /* HAVE_KILLPG */
7043
Brian Curtineb24d742010-04-12 17:16:38 +00007044
Guido van Rossumc0125471996-06-28 18:55:32 +00007045#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007046#ifdef HAVE_SYS_LOCK_H
7047#include <sys/lock.h>
7048#endif
7049
Larry Hastings2f936352014-08-05 14:04:04 +10007050/*[clinic input]
7051os.plock
7052 op: int
7053 /
7054
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007056[clinic start generated code]*/
7057
Larry Hastings2f936352014-08-05 14:04:04 +10007058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007059os_plock_impl(PyObject *module, int op)
7060/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007061{
Victor Stinner8c62be82010-05-06 00:08:46 +00007062 if (plock(op) == -1)
7063 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007064 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007065}
Larry Hastings2f936352014-08-05 14:04:04 +10007066#endif /* HAVE_PLOCK */
7067
Guido van Rossumc0125471996-06-28 18:55:32 +00007068
Guido van Rossumb6775db1994-08-01 11:34:53 +00007069#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007070/*[clinic input]
7071os.setuid
7072
7073 uid: uid_t
7074 /
7075
7076Set the current process's user id.
7077[clinic start generated code]*/
7078
Larry Hastings2f936352014-08-05 14:04:04 +10007079static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007080os_setuid_impl(PyObject *module, uid_t uid)
7081/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007082{
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 if (setuid(uid) < 0)
7084 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007085 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007086}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007087#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007089
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007090#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007091/*[clinic input]
7092os.seteuid
7093
7094 euid: uid_t
7095 /
7096
7097Set the current process's effective user id.
7098[clinic start generated code]*/
7099
Larry Hastings2f936352014-08-05 14:04:04 +10007100static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007101os_seteuid_impl(PyObject *module, uid_t euid)
7102/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007103{
7104 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007106 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007107}
7108#endif /* HAVE_SETEUID */
7109
Larry Hastings2f936352014-08-05 14:04:04 +10007110
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007111#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007112/*[clinic input]
7113os.setegid
7114
7115 egid: gid_t
7116 /
7117
7118Set the current process's effective group id.
7119[clinic start generated code]*/
7120
Larry Hastings2f936352014-08-05 14:04:04 +10007121static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007122os_setegid_impl(PyObject *module, gid_t egid)
7123/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007124{
7125 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007127 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007128}
7129#endif /* HAVE_SETEGID */
7130
Larry Hastings2f936352014-08-05 14:04:04 +10007131
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007132#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007133/*[clinic input]
7134os.setreuid
7135
7136 ruid: uid_t
7137 euid: uid_t
7138 /
7139
7140Set the current process's real and effective user ids.
7141[clinic start generated code]*/
7142
Larry Hastings2f936352014-08-05 14:04:04 +10007143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007144os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7145/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007146{
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 if (setreuid(ruid, euid) < 0) {
7148 return posix_error();
7149 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007150 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007152}
7153#endif /* HAVE_SETREUID */
7154
Larry Hastings2f936352014-08-05 14:04:04 +10007155
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007156#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007157/*[clinic input]
7158os.setregid
7159
7160 rgid: gid_t
7161 egid: gid_t
7162 /
7163
7164Set the current process's real and effective group ids.
7165[clinic start generated code]*/
7166
Larry Hastings2f936352014-08-05 14:04:04 +10007167static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007168os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7169/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007170{
7171 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007173 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007174}
7175#endif /* HAVE_SETREGID */
7176
Larry Hastings2f936352014-08-05 14:04:04 +10007177
Guido van Rossumb6775db1994-08-01 11:34:53 +00007178#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007179/*[clinic input]
7180os.setgid
7181 gid: gid_t
7182 /
7183
7184Set the current process's group id.
7185[clinic start generated code]*/
7186
Larry Hastings2f936352014-08-05 14:04:04 +10007187static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007188os_setgid_impl(PyObject *module, gid_t gid)
7189/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007190{
Victor Stinner8c62be82010-05-06 00:08:46 +00007191 if (setgid(gid) < 0)
7192 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007193 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007194}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007195#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007196
Larry Hastings2f936352014-08-05 14:04:04 +10007197
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007198#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007199/*[clinic input]
7200os.setgroups
7201
7202 groups: object
7203 /
7204
7205Set the groups of the current process to list.
7206[clinic start generated code]*/
7207
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007209os_setgroups(PyObject *module, PyObject *groups)
7210/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007211{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007212 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007214
Victor Stinner8c62be82010-05-06 00:08:46 +00007215 if (!PySequence_Check(groups)) {
7216 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7217 return NULL;
7218 }
7219 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007220 if (len < 0) {
7221 return NULL;
7222 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007223 if (len > MAX_GROUPS) {
7224 PyErr_SetString(PyExc_ValueError, "too many groups");
7225 return NULL;
7226 }
7227 for(i = 0; i < len; i++) {
7228 PyObject *elem;
7229 elem = PySequence_GetItem(groups, i);
7230 if (!elem)
7231 return NULL;
7232 if (!PyLong_Check(elem)) {
7233 PyErr_SetString(PyExc_TypeError,
7234 "groups must be integers");
7235 Py_DECREF(elem);
7236 return NULL;
7237 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007238 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007239 Py_DECREF(elem);
7240 return NULL;
7241 }
7242 }
7243 Py_DECREF(elem);
7244 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007245
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 if (setgroups(len, grouplist) < 0)
7247 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007248 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007249}
7250#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007251
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007252#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7253static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007254wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007255{
Victor Stinner8c62be82010-05-06 00:08:46 +00007256 PyObject *result;
7257 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007258 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007259
Victor Stinner8c62be82010-05-06 00:08:46 +00007260 if (pid == -1)
7261 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007262
Victor Stinner8c62be82010-05-06 00:08:46 +00007263 if (struct_rusage == NULL) {
7264 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7265 if (m == NULL)
7266 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007267 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 Py_DECREF(m);
7269 if (struct_rusage == NULL)
7270 return NULL;
7271 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007272
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7274 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7275 if (!result)
7276 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007277
7278#ifndef doubletime
7279#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7280#endif
7281
Victor Stinner8c62be82010-05-06 00:08:46 +00007282 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007283 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007284 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007285 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007286#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007287 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7288 SET_INT(result, 2, ru->ru_maxrss);
7289 SET_INT(result, 3, ru->ru_ixrss);
7290 SET_INT(result, 4, ru->ru_idrss);
7291 SET_INT(result, 5, ru->ru_isrss);
7292 SET_INT(result, 6, ru->ru_minflt);
7293 SET_INT(result, 7, ru->ru_majflt);
7294 SET_INT(result, 8, ru->ru_nswap);
7295 SET_INT(result, 9, ru->ru_inblock);
7296 SET_INT(result, 10, ru->ru_oublock);
7297 SET_INT(result, 11, ru->ru_msgsnd);
7298 SET_INT(result, 12, ru->ru_msgrcv);
7299 SET_INT(result, 13, ru->ru_nsignals);
7300 SET_INT(result, 14, ru->ru_nvcsw);
7301 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007302#undef SET_INT
7303
Victor Stinner8c62be82010-05-06 00:08:46 +00007304 if (PyErr_Occurred()) {
7305 Py_DECREF(result);
7306 return NULL;
7307 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007308
Victor Stinner8c62be82010-05-06 00:08:46 +00007309 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007310}
7311#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7312
Larry Hastings2f936352014-08-05 14:04:04 +10007313
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007314#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007315/*[clinic input]
7316os.wait3
7317
7318 options: int
7319Wait for completion of a child process.
7320
7321Returns a tuple of information about the child process:
7322 (pid, status, rusage)
7323[clinic start generated code]*/
7324
Larry Hastings2f936352014-08-05 14:04:04 +10007325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007326os_wait3_impl(PyObject *module, int options)
7327/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007328{
Victor Stinner8c62be82010-05-06 00:08:46 +00007329 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007330 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007331 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007332 WAIT_TYPE status;
7333 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007334
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007335 do {
7336 Py_BEGIN_ALLOW_THREADS
7337 pid = wait3(&status, options, &ru);
7338 Py_END_ALLOW_THREADS
7339 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7340 if (pid < 0)
7341 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007342
Victor Stinner4195b5c2012-02-08 23:03:19 +01007343 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007344}
7345#endif /* HAVE_WAIT3 */
7346
Larry Hastings2f936352014-08-05 14:04:04 +10007347
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007348#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007349/*[clinic input]
7350
7351os.wait4
7352
7353 pid: pid_t
7354 options: int
7355
7356Wait for completion of a specific child process.
7357
7358Returns a tuple of information about the child process:
7359 (pid, status, rusage)
7360[clinic start generated code]*/
7361
Larry Hastings2f936352014-08-05 14:04:04 +10007362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007363os_wait4_impl(PyObject *module, pid_t pid, int options)
7364/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007365{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007366 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007368 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 WAIT_TYPE status;
7370 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007371
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007372 do {
7373 Py_BEGIN_ALLOW_THREADS
7374 res = wait4(pid, &status, options, &ru);
7375 Py_END_ALLOW_THREADS
7376 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7377 if (res < 0)
7378 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007379
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007380 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007381}
7382#endif /* HAVE_WAIT4 */
7383
Larry Hastings2f936352014-08-05 14:04:04 +10007384
Ross Lagerwall7807c352011-03-17 20:20:30 +02007385#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007386/*[clinic input]
7387os.waitid
7388
7389 idtype: idtype_t
7390 Must be one of be P_PID, P_PGID or P_ALL.
7391 id: id_t
7392 The id to wait on.
7393 options: int
7394 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7395 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7396 /
7397
7398Returns the result of waiting for a process or processes.
7399
7400Returns either waitid_result or None if WNOHANG is specified and there are
7401no children in a waitable state.
7402[clinic start generated code]*/
7403
Larry Hastings2f936352014-08-05 14:04:04 +10007404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007405os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7406/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007407{
7408 PyObject *result;
7409 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007410 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007411 siginfo_t si;
7412 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007413
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007414 do {
7415 Py_BEGIN_ALLOW_THREADS
7416 res = waitid(idtype, id, &si, options);
7417 Py_END_ALLOW_THREADS
7418 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7419 if (res < 0)
7420 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007421
7422 if (si.si_pid == 0)
7423 Py_RETURN_NONE;
7424
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007425 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007426 if (!result)
7427 return NULL;
7428
7429 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007430 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007431 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7432 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7433 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7434 if (PyErr_Occurred()) {
7435 Py_DECREF(result);
7436 return NULL;
7437 }
7438
7439 return result;
7440}
Larry Hastings2f936352014-08-05 14:04:04 +10007441#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007442
Larry Hastings2f936352014-08-05 14:04:04 +10007443
7444#if defined(HAVE_WAITPID)
7445/*[clinic input]
7446os.waitpid
7447 pid: pid_t
7448 options: int
7449 /
7450
7451Wait for completion of a given child process.
7452
7453Returns a tuple of information regarding the child process:
7454 (pid, status)
7455
7456The options argument is ignored on Windows.
7457[clinic start generated code]*/
7458
Larry Hastings2f936352014-08-05 14:04:04 +10007459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007460os_waitpid_impl(PyObject *module, pid_t pid, int options)
7461/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007462{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007463 pid_t res;
7464 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007465 WAIT_TYPE status;
7466 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007467
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007468 do {
7469 Py_BEGIN_ALLOW_THREADS
7470 res = waitpid(pid, &status, options);
7471 Py_END_ALLOW_THREADS
7472 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7473 if (res < 0)
7474 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007475
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007476 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007477}
Tim Petersab034fa2002-02-01 11:27:43 +00007478#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007479/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007480/*[clinic input]
7481os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007482 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007483 options: int
7484 /
7485
7486Wait for completion of a given process.
7487
7488Returns a tuple of information regarding the process:
7489 (pid, status << 8)
7490
7491The options argument is ignored on Windows.
7492[clinic start generated code]*/
7493
Larry Hastings2f936352014-08-05 14:04:04 +10007494static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007495os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007496/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007497{
7498 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007499 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007500 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007501
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007502 do {
7503 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007504 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007505 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007506 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007507 Py_END_ALLOW_THREADS
7508 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007509 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007510 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007511
Victor Stinner8c62be82010-05-06 00:08:46 +00007512 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007513 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007514}
Larry Hastings2f936352014-08-05 14:04:04 +10007515#endif
7516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007517
Guido van Rossumad0ee831995-03-01 10:34:45 +00007518#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007519/*[clinic input]
7520os.wait
7521
7522Wait for completion of a child process.
7523
7524Returns a tuple of information about the child process:
7525 (pid, status)
7526[clinic start generated code]*/
7527
Larry Hastings2f936352014-08-05 14:04:04 +10007528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007529os_wait_impl(PyObject *module)
7530/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007531{
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007533 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007534 WAIT_TYPE status;
7535 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007536
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007537 do {
7538 Py_BEGIN_ALLOW_THREADS
7539 pid = wait(&status);
7540 Py_END_ALLOW_THREADS
7541 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7542 if (pid < 0)
7543 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007544
Victor Stinner8c62be82010-05-06 00:08:46 +00007545 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007546}
Larry Hastings2f936352014-08-05 14:04:04 +10007547#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007549
Larry Hastings9cf065c2012-06-22 16:30:09 -07007550#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007551/*[clinic input]
7552os.readlink
7553
7554 path: path_t
7555 *
7556 dir_fd: dir_fd(requires='readlinkat') = None
7557
7558Return a string representing the path to which the symbolic link points.
7559
7560If dir_fd is not None, it should be a file descriptor open to a directory,
7561and path should be relative; path will then be relative to that directory.
7562
7563dir_fd may not be implemented on your platform. If it is unavailable,
7564using it will raise a NotImplementedError.
7565[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007566
Barry Warsaw53699e91996-12-10 23:23:01 +00007567static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007568os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7569/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007570{
Berker Peksage0b5b202018-08-15 13:03:41 +03007571#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007572 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007573 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007574
7575 Py_BEGIN_ALLOW_THREADS
7576#ifdef HAVE_READLINKAT
7577 if (dir_fd != DEFAULT_DIR_FD)
7578 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7579 else
7580#endif
7581 length = readlink(path->narrow, buffer, MAXPATHLEN);
7582 Py_END_ALLOW_THREADS
7583
7584 if (length < 0) {
7585 return path_error(path);
7586 }
7587 buffer[length] = '\0';
7588
7589 if (PyUnicode_Check(path->object))
7590 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7591 else
7592 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007593#elif defined(MS_WINDOWS)
7594 DWORD n_bytes_returned;
7595 DWORD io_result;
7596 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007597 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7598 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7599 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007600 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007601
Larry Hastings2f936352014-08-05 14:04:04 +10007602 /* First get a handle to the reparse point */
7603 Py_BEGIN_ALLOW_THREADS
7604 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007605 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007606 0,
7607 0,
7608 0,
7609 OPEN_EXISTING,
7610 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7611 0);
7612 Py_END_ALLOW_THREADS
7613
Berker Peksage0b5b202018-08-15 13:03:41 +03007614 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007615 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007616 }
Larry Hastings2f936352014-08-05 14:04:04 +10007617
7618 Py_BEGIN_ALLOW_THREADS
7619 /* New call DeviceIoControl to read the reparse point */
7620 io_result = DeviceIoControl(
7621 reparse_point_handle,
7622 FSCTL_GET_REPARSE_POINT,
7623 0, 0, /* in buffer */
7624 target_buffer, sizeof(target_buffer),
7625 &n_bytes_returned,
7626 0 /* we're not using OVERLAPPED_IO */
7627 );
7628 CloseHandle(reparse_point_handle);
7629 Py_END_ALLOW_THREADS
7630
Berker Peksage0b5b202018-08-15 13:03:41 +03007631 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007632 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007633 }
Larry Hastings2f936352014-08-05 14:04:04 +10007634
7635 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7636 {
7637 PyErr_SetString(PyExc_ValueError,
7638 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007639 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007640 }
SSE43c34aad2018-02-13 00:10:35 +07007641 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7642 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007643
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007644 result = PyUnicode_FromWideChar(print_name,
7645 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7646 if (path->narrow) {
7647 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007648 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007649 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007650#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007651}
Berker Peksage0b5b202018-08-15 13:03:41 +03007652#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007653
Larry Hastings9cf065c2012-06-22 16:30:09 -07007654#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007655
7656#if defined(MS_WINDOWS)
7657
7658/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Steve Dower6921e732018-03-05 14:26:08 -08007659static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007660
Larry Hastings9cf065c2012-06-22 16:30:09 -07007661static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007662check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007663{
7664 HINSTANCE hKernel32;
7665 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007666 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007667 return 1;
7668 hKernel32 = GetModuleHandleW(L"KERNEL32");
7669 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7670 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007671 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007672}
7673
Steve Dower6921e732018-03-05 14:26:08 -08007674/* Remove the last portion of the path - return 0 on success */
7675static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007676_dirnameW(WCHAR *path)
7677{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007678 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007679 size_t length = wcsnlen_s(path, MAX_PATH);
7680 if (length == MAX_PATH) {
7681 return -1;
7682 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007683
7684 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007685 for(ptr = path + length; ptr != path; ptr--) {
7686 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007687 break;
Steve Dower6921e732018-03-05 14:26:08 -08007688 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007689 }
7690 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007691 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007692}
7693
Victor Stinner31b3b922013-06-05 01:49:17 +02007694/* Is this path absolute? */
7695static int
7696_is_absW(const WCHAR *path)
7697{
Steve Dower6921e732018-03-05 14:26:08 -08007698 return path[0] == L'\\' || path[0] == L'/' ||
7699 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007700}
7701
Steve Dower6921e732018-03-05 14:26:08 -08007702/* join root and rest with a backslash - return 0 on success */
7703static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007704_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7705{
Victor Stinner31b3b922013-06-05 01:49:17 +02007706 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007707 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007708 }
7709
Steve Dower6921e732018-03-05 14:26:08 -08007710 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7711 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007712 }
Steve Dower6921e732018-03-05 14:26:08 -08007713
7714 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7715 return -1;
7716 }
7717
7718 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007719}
7720
Victor Stinner31b3b922013-06-05 01:49:17 +02007721/* Return True if the path at src relative to dest is a directory */
7722static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007723_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007724{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007725 WIN32_FILE_ATTRIBUTE_DATA src_info;
7726 WCHAR dest_parent[MAX_PATH];
7727 WCHAR src_resolved[MAX_PATH] = L"";
7728
7729 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007730 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7731 _dirnameW(dest_parent)) {
7732 return 0;
7733 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007734 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007735 if (_joinW(src_resolved, dest_parent, src)) {
7736 return 0;
7737 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007738 return (
7739 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7740 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7741 );
7742}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007744
Larry Hastings2f936352014-08-05 14:04:04 +10007745
7746/*[clinic input]
7747os.symlink
7748 src: path_t
7749 dst: path_t
7750 target_is_directory: bool = False
7751 *
7752 dir_fd: dir_fd(requires='symlinkat')=None
7753
7754# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7755
7756Create a symbolic link pointing to src named dst.
7757
7758target_is_directory is required on Windows if the target is to be
7759 interpreted as a directory. (On Windows, symlink requires
7760 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7761 target_is_directory is ignored on non-Windows platforms.
7762
7763If dir_fd is not None, it should be a file descriptor open to a directory,
7764 and path should be relative; path will then be relative to that directory.
7765dir_fd may not be implemented on your platform.
7766 If it is unavailable, using it will raise a NotImplementedError.
7767
7768[clinic start generated code]*/
7769
Larry Hastings2f936352014-08-05 14:04:04 +10007770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007771os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007772 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007773/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007774{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007775#ifdef MS_WINDOWS
7776 DWORD result;
7777#else
7778 int result;
7779#endif
7780
Larry Hastings9cf065c2012-06-22 16:30:09 -07007781#ifdef MS_WINDOWS
7782 if (!check_CreateSymbolicLink()) {
7783 PyErr_SetString(PyExc_NotImplementedError,
7784 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007785 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007786 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007787 if (!win32_can_symlink) {
7788 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007789 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007790 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007791#endif
7792
Larry Hastings9cf065c2012-06-22 16:30:09 -07007793#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007794
Larry Hastings9cf065c2012-06-22 16:30:09 -07007795 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007796 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007797 /* if src is a directory, ensure target_is_directory==1 */
7798 target_is_directory |= _check_dirW(src->wide, dst->wide);
7799 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7800 target_is_directory);
Steve Dower6921e732018-03-05 14:26:08 -08007801 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007802 Py_END_ALLOW_THREADS
7803
Larry Hastings2f936352014-08-05 14:04:04 +10007804 if (!result)
7805 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007806
7807#else
7808
Steve Dower6921e732018-03-05 14:26:08 -08007809 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7810 PyErr_SetString(PyExc_ValueError,
7811 "symlink: src and dst must be the same type");
7812 return NULL;
7813 }
7814
Larry Hastings9cf065c2012-06-22 16:30:09 -07007815 Py_BEGIN_ALLOW_THREADS
7816#if HAVE_SYMLINKAT
7817 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007818 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007819 else
7820#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007821 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007822 Py_END_ALLOW_THREADS
7823
Larry Hastings2f936352014-08-05 14:04:04 +10007824 if (result)
7825 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007826#endif
7827
Larry Hastings2f936352014-08-05 14:04:04 +10007828 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007829}
7830#endif /* HAVE_SYMLINK */
7831
Larry Hastings9cf065c2012-06-22 16:30:09 -07007832
Brian Curtind40e6f72010-07-08 21:39:08 +00007833
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007834
Larry Hastings605a62d2012-06-24 04:33:36 -07007835static PyStructSequence_Field times_result_fields[] = {
7836 {"user", "user time"},
7837 {"system", "system time"},
7838 {"children_user", "user time of children"},
7839 {"children_system", "system time of children"},
7840 {"elapsed", "elapsed time since an arbitrary point in the past"},
7841 {NULL}
7842};
7843
7844PyDoc_STRVAR(times_result__doc__,
7845"times_result: Result from os.times().\n\n\
7846This object may be accessed either as a tuple of\n\
7847 (user, system, children_user, children_system, elapsed),\n\
7848or via the attributes user, system, children_user, children_system,\n\
7849and elapsed.\n\
7850\n\
7851See os.times for more information.");
7852
7853static PyStructSequence_Desc times_result_desc = {
7854 "times_result", /* name */
7855 times_result__doc__, /* doc */
7856 times_result_fields,
7857 5
7858};
7859
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007860static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07007861
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007862#ifdef MS_WINDOWS
7863#define HAVE_TIMES /* mandatory, for the method table */
7864#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007865
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007866#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007867
7868static PyObject *
7869build_times_result(double user, double system,
7870 double children_user, double children_system,
7871 double elapsed)
7872{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007873 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07007874 if (value == NULL)
7875 return NULL;
7876
7877#define SET(i, field) \
7878 { \
7879 PyObject *o = PyFloat_FromDouble(field); \
7880 if (!o) { \
7881 Py_DECREF(value); \
7882 return NULL; \
7883 } \
7884 PyStructSequence_SET_ITEM(value, i, o); \
7885 } \
7886
7887 SET(0, user);
7888 SET(1, system);
7889 SET(2, children_user);
7890 SET(3, children_system);
7891 SET(4, elapsed);
7892
7893#undef SET
7894
7895 return value;
7896}
7897
Larry Hastings605a62d2012-06-24 04:33:36 -07007898
Larry Hastings2f936352014-08-05 14:04:04 +10007899#ifndef MS_WINDOWS
7900#define NEED_TICKS_PER_SECOND
7901static long ticks_per_second = -1;
7902#endif /* MS_WINDOWS */
7903
7904/*[clinic input]
7905os.times
7906
7907Return a collection containing process timing information.
7908
7909The object returned behaves like a named tuple with these fields:
7910 (utime, stime, cutime, cstime, elapsed_time)
7911All fields are floating point numbers.
7912[clinic start generated code]*/
7913
Larry Hastings2f936352014-08-05 14:04:04 +10007914static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007915os_times_impl(PyObject *module)
7916/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007917#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007918{
Victor Stinner8c62be82010-05-06 00:08:46 +00007919 FILETIME create, exit, kernel, user;
7920 HANDLE hProc;
7921 hProc = GetCurrentProcess();
7922 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7923 /* The fields of a FILETIME structure are the hi and lo part
7924 of a 64-bit value expressed in 100 nanosecond units.
7925 1e7 is one second in such units; 1e-7 the inverse.
7926 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7927 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007928 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 (double)(user.dwHighDateTime*429.4967296 +
7930 user.dwLowDateTime*1e-7),
7931 (double)(kernel.dwHighDateTime*429.4967296 +
7932 kernel.dwLowDateTime*1e-7),
7933 (double)0,
7934 (double)0,
7935 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007936}
Larry Hastings2f936352014-08-05 14:04:04 +10007937#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007938{
Larry Hastings2f936352014-08-05 14:04:04 +10007939
7940
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007941 struct tms t;
7942 clock_t c;
7943 errno = 0;
7944 c = times(&t);
7945 if (c == (clock_t) -1)
7946 return posix_error();
7947 return build_times_result(
7948 (double)t.tms_utime / ticks_per_second,
7949 (double)t.tms_stime / ticks_per_second,
7950 (double)t.tms_cutime / ticks_per_second,
7951 (double)t.tms_cstime / ticks_per_second,
7952 (double)c / ticks_per_second);
7953}
Larry Hastings2f936352014-08-05 14:04:04 +10007954#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007955#endif /* HAVE_TIMES */
7956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007957
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007958#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007959/*[clinic input]
7960os.getsid
7961
7962 pid: pid_t
7963 /
7964
7965Call the system call getsid(pid) and return the result.
7966[clinic start generated code]*/
7967
Larry Hastings2f936352014-08-05 14:04:04 +10007968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007969os_getsid_impl(PyObject *module, pid_t pid)
7970/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007971{
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 sid = getsid(pid);
7974 if (sid < 0)
7975 return posix_error();
7976 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007977}
7978#endif /* HAVE_GETSID */
7979
7980
Guido van Rossumb6775db1994-08-01 11:34:53 +00007981#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007982/*[clinic input]
7983os.setsid
7984
7985Call the system call setsid().
7986[clinic start generated code]*/
7987
Larry Hastings2f936352014-08-05 14:04:04 +10007988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007989os_setsid_impl(PyObject *module)
7990/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007991{
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 if (setsid() < 0)
7993 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007994 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007995}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007996#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007997
Larry Hastings2f936352014-08-05 14:04:04 +10007998
Guido van Rossumb6775db1994-08-01 11:34:53 +00007999#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008000/*[clinic input]
8001os.setpgid
8002
8003 pid: pid_t
8004 pgrp: pid_t
8005 /
8006
8007Call the system call setpgid(pid, pgrp).
8008[clinic start generated code]*/
8009
Larry Hastings2f936352014-08-05 14:04:04 +10008010static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008011os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8012/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008013{
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 if (setpgid(pid, pgrp) < 0)
8015 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008016 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008017}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008018#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008019
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008020
Guido van Rossumb6775db1994-08-01 11:34:53 +00008021#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008022/*[clinic input]
8023os.tcgetpgrp
8024
8025 fd: int
8026 /
8027
8028Return the process group associated with the terminal specified by fd.
8029[clinic start generated code]*/
8030
Larry Hastings2f936352014-08-05 14:04:04 +10008031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008032os_tcgetpgrp_impl(PyObject *module, int fd)
8033/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008034{
8035 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 if (pgid < 0)
8037 return posix_error();
8038 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008039}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008040#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008042
Guido van Rossumb6775db1994-08-01 11:34:53 +00008043#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008044/*[clinic input]
8045os.tcsetpgrp
8046
8047 fd: int
8048 pgid: pid_t
8049 /
8050
8051Set the process group associated with the terminal specified by fd.
8052[clinic start generated code]*/
8053
Larry Hastings2f936352014-08-05 14:04:04 +10008054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008055os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8056/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008057{
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 if (tcsetpgrp(fd, pgid) < 0)
8059 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008060 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008061}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008062#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008063
Guido van Rossum687dd131993-05-17 08:34:16 +00008064/* Functions acting on file descriptors */
8065
Victor Stinnerdaf45552013-08-28 00:53:59 +02008066#ifdef O_CLOEXEC
8067extern int _Py_open_cloexec_works;
8068#endif
8069
Larry Hastings2f936352014-08-05 14:04:04 +10008070
8071/*[clinic input]
8072os.open -> int
8073 path: path_t
8074 flags: int
8075 mode: int = 0o777
8076 *
8077 dir_fd: dir_fd(requires='openat') = None
8078
8079# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8080
8081Open a file for low level IO. Returns a file descriptor (integer).
8082
8083If dir_fd is not None, it should be a file descriptor open to a directory,
8084 and path should be relative; path will then be relative to that directory.
8085dir_fd may not be implemented on your platform.
8086 If it is unavailable, using it will raise a NotImplementedError.
8087[clinic start generated code]*/
8088
Larry Hastings2f936352014-08-05 14:04:04 +10008089static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008090os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8091/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008092{
8093 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008094 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008095
Victor Stinnerdaf45552013-08-28 00:53:59 +02008096#ifdef O_CLOEXEC
8097 int *atomic_flag_works = &_Py_open_cloexec_works;
8098#elif !defined(MS_WINDOWS)
8099 int *atomic_flag_works = NULL;
8100#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008101
Victor Stinnerdaf45552013-08-28 00:53:59 +02008102#ifdef MS_WINDOWS
8103 flags |= O_NOINHERIT;
8104#elif defined(O_CLOEXEC)
8105 flags |= O_CLOEXEC;
8106#endif
8107
Steve Dower8fc89802015-04-12 00:26:27 -04008108 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008109 do {
8110 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008111#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008112 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008113#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008114#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008115 if (dir_fd != DEFAULT_DIR_FD)
8116 fd = openat(dir_fd, path->narrow, flags, mode);
8117 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008118#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008119 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008120#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008121 Py_END_ALLOW_THREADS
8122 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008123 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008124
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008125 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008126 if (!async_err)
8127 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008128 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008129 }
8130
Victor Stinnerdaf45552013-08-28 00:53:59 +02008131#ifndef MS_WINDOWS
8132 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8133 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008134 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008135 }
8136#endif
8137
Larry Hastings2f936352014-08-05 14:04:04 +10008138 return fd;
8139}
8140
8141
8142/*[clinic input]
8143os.close
8144
8145 fd: int
8146
8147Close a file descriptor.
8148[clinic start generated code]*/
8149
Barry Warsaw53699e91996-12-10 23:23:01 +00008150static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008151os_close_impl(PyObject *module, int fd)
8152/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008153{
Larry Hastings2f936352014-08-05 14:04:04 +10008154 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008155 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8156 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8157 * for more details.
8158 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008159 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008160 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008161 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008162 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 Py_END_ALLOW_THREADS
8164 if (res < 0)
8165 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008166 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008167}
8168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008169
Larry Hastings2f936352014-08-05 14:04:04 +10008170/*[clinic input]
8171os.closerange
8172
8173 fd_low: int
8174 fd_high: int
8175 /
8176
8177Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8178[clinic start generated code]*/
8179
Larry Hastings2f936352014-08-05 14:04:04 +10008180static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008181os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8182/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008183{
8184 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008186 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008187 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008188 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008189 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 Py_END_ALLOW_THREADS
8191 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008192}
8193
8194
Larry Hastings2f936352014-08-05 14:04:04 +10008195/*[clinic input]
8196os.dup -> int
8197
8198 fd: int
8199 /
8200
8201Return a duplicate of a file descriptor.
8202[clinic start generated code]*/
8203
Larry Hastings2f936352014-08-05 14:04:04 +10008204static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008205os_dup_impl(PyObject *module, int fd)
8206/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008207{
8208 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008209}
8210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008211
Larry Hastings2f936352014-08-05 14:04:04 +10008212/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008213os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008214 fd: int
8215 fd2: int
8216 inheritable: bool=True
8217
8218Duplicate file descriptor.
8219[clinic start generated code]*/
8220
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008221static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008222os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008223/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008224{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008225 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008226#if defined(HAVE_DUP3) && \
8227 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8228 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008229 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008230#endif
8231
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008232 if (fd < 0 || fd2 < 0) {
8233 posix_error();
8234 return -1;
8235 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008236
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008237 /* dup2() can fail with EINTR if the target FD is already open, because it
8238 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8239 * upon close(), and therefore below.
8240 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008241#ifdef MS_WINDOWS
8242 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008243 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008245 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008246 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008247 if (res < 0) {
8248 posix_error();
8249 return -1;
8250 }
8251 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008252
8253 /* Character files like console cannot be make non-inheritable */
8254 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8255 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008256 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008257 }
8258
8259#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8260 Py_BEGIN_ALLOW_THREADS
8261 if (!inheritable)
8262 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8263 else
8264 res = dup2(fd, fd2);
8265 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008266 if (res < 0) {
8267 posix_error();
8268 return -1;
8269 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008270
8271#else
8272
8273#ifdef HAVE_DUP3
8274 if (!inheritable && dup3_works != 0) {
8275 Py_BEGIN_ALLOW_THREADS
8276 res = dup3(fd, fd2, O_CLOEXEC);
8277 Py_END_ALLOW_THREADS
8278 if (res < 0) {
8279 if (dup3_works == -1)
8280 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008281 if (dup3_works) {
8282 posix_error();
8283 return -1;
8284 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008285 }
8286 }
8287
8288 if (inheritable || dup3_works == 0)
8289 {
8290#endif
8291 Py_BEGIN_ALLOW_THREADS
8292 res = dup2(fd, fd2);
8293 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008294 if (res < 0) {
8295 posix_error();
8296 return -1;
8297 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008298
8299 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8300 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008301 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008302 }
8303#ifdef HAVE_DUP3
8304 }
8305#endif
8306
8307#endif
8308
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008309 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008310}
8311
Larry Hastings2f936352014-08-05 14:04:04 +10008312
Ross Lagerwall7807c352011-03-17 20:20:30 +02008313#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008314/*[clinic input]
8315os.lockf
8316
8317 fd: int
8318 An open file descriptor.
8319 command: int
8320 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8321 length: Py_off_t
8322 The number of bytes to lock, starting at the current position.
8323 /
8324
8325Apply, test or remove a POSIX lock on an open file descriptor.
8326
8327[clinic start generated code]*/
8328
Larry Hastings2f936352014-08-05 14:04:04 +10008329static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008330os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8331/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008332{
8333 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008334
8335 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008336 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008337 Py_END_ALLOW_THREADS
8338
8339 if (res < 0)
8340 return posix_error();
8341
8342 Py_RETURN_NONE;
8343}
Larry Hastings2f936352014-08-05 14:04:04 +10008344#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008346
Larry Hastings2f936352014-08-05 14:04:04 +10008347/*[clinic input]
8348os.lseek -> Py_off_t
8349
8350 fd: int
8351 position: Py_off_t
8352 how: int
8353 /
8354
8355Set the position of a file descriptor. Return the new position.
8356
8357Return the new cursor position in number of bytes
8358relative to the beginning of the file.
8359[clinic start generated code]*/
8360
Larry Hastings2f936352014-08-05 14:04:04 +10008361static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008362os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8363/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008364{
8365 Py_off_t result;
8366
Guido van Rossum687dd131993-05-17 08:34:16 +00008367#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008368 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8369 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008370 case 0: how = SEEK_SET; break;
8371 case 1: how = SEEK_CUR; break;
8372 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008374#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008375
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008377 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008378#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008379 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008380#else
Larry Hastings2f936352014-08-05 14:04:04 +10008381 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008382#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008383 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008385 if (result < 0)
8386 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008387
Larry Hastings2f936352014-08-05 14:04:04 +10008388 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008389}
8390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008391
Larry Hastings2f936352014-08-05 14:04:04 +10008392/*[clinic input]
8393os.read
8394 fd: int
8395 length: Py_ssize_t
8396 /
8397
8398Read from a file descriptor. Returns a bytes object.
8399[clinic start generated code]*/
8400
Larry Hastings2f936352014-08-05 14:04:04 +10008401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008402os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8403/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008404{
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 Py_ssize_t n;
8406 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008407
8408 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 errno = EINVAL;
8410 return posix_error();
8411 }
Larry Hastings2f936352014-08-05 14:04:04 +10008412
8413#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008414 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008415 if (length > INT_MAX)
8416 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008417#endif
8418
8419 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 if (buffer == NULL)
8421 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422
Victor Stinner66aab0c2015-03-19 22:53:20 +01008423 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8424 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008426 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 }
Larry Hastings2f936352014-08-05 14:04:04 +10008428
8429 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008430 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008431
Victor Stinner8c62be82010-05-06 00:08:46 +00008432 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008433}
8434
Ross Lagerwall7807c352011-03-17 20:20:30 +02008435#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008436 || defined(__APPLE__))) \
8437 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8438 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8439static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008440iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008441{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008442 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008443
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008444 *iov = PyMem_New(struct iovec, cnt);
8445 if (*iov == NULL) {
8446 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008447 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008448 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008449
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008450 *buf = PyMem_New(Py_buffer, cnt);
8451 if (*buf == NULL) {
8452 PyMem_Del(*iov);
8453 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008454 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008455 }
8456
8457 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008458 PyObject *item = PySequence_GetItem(seq, i);
8459 if (item == NULL)
8460 goto fail;
8461 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8462 Py_DECREF(item);
8463 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008464 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008465 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008466 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008467 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008468 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008469 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008470
8471fail:
8472 PyMem_Del(*iov);
8473 for (j = 0; j < i; j++) {
8474 PyBuffer_Release(&(*buf)[j]);
8475 }
8476 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008477 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008478}
8479
8480static void
8481iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8482{
8483 int i;
8484 PyMem_Del(iov);
8485 for (i = 0; i < cnt; i++) {
8486 PyBuffer_Release(&buf[i]);
8487 }
8488 PyMem_Del(buf);
8489}
8490#endif
8491
Larry Hastings2f936352014-08-05 14:04:04 +10008492
Ross Lagerwall7807c352011-03-17 20:20:30 +02008493#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008494/*[clinic input]
8495os.readv -> Py_ssize_t
8496
8497 fd: int
8498 buffers: object
8499 /
8500
8501Read from a file descriptor fd into an iterable of buffers.
8502
8503The buffers should be mutable buffers accepting bytes.
8504readv will transfer data into each buffer until it is full
8505and then move on to the next buffer in the sequence to hold
8506the rest of the data.
8507
8508readv returns the total number of bytes read,
8509which may be less than the total capacity of all the buffers.
8510[clinic start generated code]*/
8511
Larry Hastings2f936352014-08-05 14:04:04 +10008512static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008513os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8514/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008515{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008516 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008517 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008518 struct iovec *iov;
8519 Py_buffer *buf;
8520
Larry Hastings2f936352014-08-05 14:04:04 +10008521 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008522 PyErr_SetString(PyExc_TypeError,
8523 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008524 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008525 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008526
Larry Hastings2f936352014-08-05 14:04:04 +10008527 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008528 if (cnt < 0)
8529 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008530
8531 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8532 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008533
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008534 do {
8535 Py_BEGIN_ALLOW_THREADS
8536 n = readv(fd, iov, cnt);
8537 Py_END_ALLOW_THREADS
8538 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008539
8540 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008541 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008542 if (!async_err)
8543 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008544 return -1;
8545 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008546
Larry Hastings2f936352014-08-05 14:04:04 +10008547 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008548}
Larry Hastings2f936352014-08-05 14:04:04 +10008549#endif /* HAVE_READV */
8550
Ross Lagerwall7807c352011-03-17 20:20:30 +02008551
8552#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008553/*[clinic input]
8554# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8555os.pread
8556
8557 fd: int
8558 length: int
8559 offset: Py_off_t
8560 /
8561
8562Read a number of bytes from a file descriptor starting at a particular offset.
8563
8564Read length bytes from file descriptor fd, starting at offset bytes from
8565the beginning of the file. The file offset remains unchanged.
8566[clinic start generated code]*/
8567
Larry Hastings2f936352014-08-05 14:04:04 +10008568static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008569os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8570/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008571{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008572 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008573 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008574 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008575
Larry Hastings2f936352014-08-05 14:04:04 +10008576 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008577 errno = EINVAL;
8578 return posix_error();
8579 }
Larry Hastings2f936352014-08-05 14:04:04 +10008580 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008581 if (buffer == NULL)
8582 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008583
8584 do {
8585 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008586 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008587 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008588 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008589 Py_END_ALLOW_THREADS
8590 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8591
Ross Lagerwall7807c352011-03-17 20:20:30 +02008592 if (n < 0) {
8593 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008594 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008595 }
Larry Hastings2f936352014-08-05 14:04:04 +10008596 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008597 _PyBytes_Resize(&buffer, n);
8598 return buffer;
8599}
Larry Hastings2f936352014-08-05 14:04:04 +10008600#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008601
Pablo Galindo4defba32018-01-27 16:16:37 +00008602#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8603/*[clinic input]
8604os.preadv -> Py_ssize_t
8605
8606 fd: int
8607 buffers: object
8608 offset: Py_off_t
8609 flags: int = 0
8610 /
8611
8612Reads from a file descriptor into a number of mutable bytes-like objects.
8613
8614Combines the functionality of readv() and pread(). As readv(), it will
8615transfer data into each buffer until it is full and then move on to the next
8616buffer in the sequence to hold the rest of the data. Its fourth argument,
8617specifies the file offset at which the input operation is to be performed. It
8618will return the total number of bytes read (which can be less than the total
8619capacity of all the objects).
8620
8621The flags argument contains a bitwise OR of zero or more of the following flags:
8622
8623- RWF_HIPRI
8624- RWF_NOWAIT
8625
8626Using non-zero flags requires Linux 4.6 or newer.
8627[clinic start generated code]*/
8628
8629static Py_ssize_t
8630os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8631 int flags)
8632/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8633{
8634 Py_ssize_t cnt, n;
8635 int async_err = 0;
8636 struct iovec *iov;
8637 Py_buffer *buf;
8638
8639 if (!PySequence_Check(buffers)) {
8640 PyErr_SetString(PyExc_TypeError,
8641 "preadv2() arg 2 must be a sequence");
8642 return -1;
8643 }
8644
8645 cnt = PySequence_Size(buffers);
8646 if (cnt < 0) {
8647 return -1;
8648 }
8649
8650#ifndef HAVE_PREADV2
8651 if(flags != 0) {
8652 argument_unavailable_error("preadv2", "flags");
8653 return -1;
8654 }
8655#endif
8656
8657 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8658 return -1;
8659 }
8660#ifdef HAVE_PREADV2
8661 do {
8662 Py_BEGIN_ALLOW_THREADS
8663 _Py_BEGIN_SUPPRESS_IPH
8664 n = preadv2(fd, iov, cnt, offset, flags);
8665 _Py_END_SUPPRESS_IPH
8666 Py_END_ALLOW_THREADS
8667 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8668#else
8669 do {
8670 Py_BEGIN_ALLOW_THREADS
8671 _Py_BEGIN_SUPPRESS_IPH
8672 n = preadv(fd, iov, cnt, offset);
8673 _Py_END_SUPPRESS_IPH
8674 Py_END_ALLOW_THREADS
8675 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8676#endif
8677
8678 iov_cleanup(iov, buf, cnt);
8679 if (n < 0) {
8680 if (!async_err) {
8681 posix_error();
8682 }
8683 return -1;
8684 }
8685
8686 return n;
8687}
8688#endif /* HAVE_PREADV */
8689
Larry Hastings2f936352014-08-05 14:04:04 +10008690
8691/*[clinic input]
8692os.write -> Py_ssize_t
8693
8694 fd: int
8695 data: Py_buffer
8696 /
8697
8698Write a bytes object to a file descriptor.
8699[clinic start generated code]*/
8700
Larry Hastings2f936352014-08-05 14:04:04 +10008701static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008702os_write_impl(PyObject *module, int fd, Py_buffer *data)
8703/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008704{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008705 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008706}
8707
8708#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008709PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008710"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008711sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008712 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008713Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008714
Larry Hastings2f936352014-08-05 14:04:04 +10008715/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008716static PyObject *
8717posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8718{
8719 int in, out;
8720 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008721 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008722 off_t offset;
8723
8724#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8725#ifndef __APPLE__
8726 Py_ssize_t len;
8727#endif
8728 PyObject *headers = NULL, *trailers = NULL;
8729 Py_buffer *hbuf, *tbuf;
8730 off_t sbytes;
8731 struct sf_hdtr sf;
8732 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008733 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008734 static char *keywords[] = {"out", "in",
8735 "offset", "count",
8736 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008737
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008738 sf.headers = NULL;
8739 sf.trailers = NULL;
8740
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008741#ifdef __APPLE__
8742 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008743 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008744#else
8745 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008746 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008747#endif
8748 &headers, &trailers, &flags))
8749 return NULL;
8750 if (headers != NULL) {
8751 if (!PySequence_Check(headers)) {
8752 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008753 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008754 return NULL;
8755 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008756 Py_ssize_t i = PySequence_Size(headers);
8757 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008758 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008759 if (i > INT_MAX) {
8760 PyErr_SetString(PyExc_OverflowError,
8761 "sendfile() header is too large");
8762 return NULL;
8763 }
8764 if (i > 0) {
8765 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008766 if (iov_setup(&(sf.headers), &hbuf,
8767 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008768 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008769#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008770 for (i = 0; i < sf.hdr_cnt; i++) {
8771 Py_ssize_t blen = sf.headers[i].iov_len;
8772# define OFF_T_MAX 0x7fffffffffffffff
8773 if (sbytes >= OFF_T_MAX - blen) {
8774 PyErr_SetString(PyExc_OverflowError,
8775 "sendfile() header is too large");
8776 return NULL;
8777 }
8778 sbytes += blen;
8779 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008780#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008781 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008782 }
8783 }
8784 if (trailers != NULL) {
8785 if (!PySequence_Check(trailers)) {
8786 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008787 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008788 return NULL;
8789 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008790 Py_ssize_t i = PySequence_Size(trailers);
8791 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008792 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008793 if (i > INT_MAX) {
8794 PyErr_SetString(PyExc_OverflowError,
8795 "sendfile() trailer is too large");
8796 return NULL;
8797 }
8798 if (i > 0) {
8799 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008800 if (iov_setup(&(sf.trailers), &tbuf,
8801 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008802 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008803 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008804 }
8805 }
8806
Steve Dower8fc89802015-04-12 00:26:27 -04008807 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008808 do {
8809 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008810#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008811 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008812#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008813 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008814#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008815 Py_END_ALLOW_THREADS
8816 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008817 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008818
8819 if (sf.headers != NULL)
8820 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8821 if (sf.trailers != NULL)
8822 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8823
8824 if (ret < 0) {
8825 if ((errno == EAGAIN) || (errno == EBUSY)) {
8826 if (sbytes != 0) {
8827 // some data has been sent
8828 goto done;
8829 }
8830 else {
8831 // no data has been sent; upper application is supposed
8832 // to retry on EAGAIN or EBUSY
8833 return posix_error();
8834 }
8835 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008836 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008837 }
8838 goto done;
8839
8840done:
8841 #if !defined(HAVE_LARGEFILE_SUPPORT)
8842 return Py_BuildValue("l", sbytes);
8843 #else
8844 return Py_BuildValue("L", sbytes);
8845 #endif
8846
8847#else
8848 Py_ssize_t count;
8849 PyObject *offobj;
8850 static char *keywords[] = {"out", "in",
8851 "offset", "count", NULL};
8852 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8853 keywords, &out, &in, &offobj, &count))
8854 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008855#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008856 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008857 do {
8858 Py_BEGIN_ALLOW_THREADS
8859 ret = sendfile(out, in, NULL, count);
8860 Py_END_ALLOW_THREADS
8861 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008862 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008863 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008864 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008865 }
8866#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008867 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008868 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008869
8870 do {
8871 Py_BEGIN_ALLOW_THREADS
8872 ret = sendfile(out, in, &offset, count);
8873 Py_END_ALLOW_THREADS
8874 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008875 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008876 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008877 return Py_BuildValue("n", ret);
8878#endif
8879}
Larry Hastings2f936352014-08-05 14:04:04 +10008880#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008881
Larry Hastings2f936352014-08-05 14:04:04 +10008882
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008883#if defined(__APPLE__)
8884/*[clinic input]
8885os._fcopyfile
8886
8887 infd: int
8888 outfd: int
8889 flags: int
8890 /
8891
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008892Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008893[clinic start generated code]*/
8894
8895static PyObject *
8896os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008897/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008898{
8899 int ret;
8900
8901 Py_BEGIN_ALLOW_THREADS
8902 ret = fcopyfile(infd, outfd, NULL, flags);
8903 Py_END_ALLOW_THREADS
8904 if (ret < 0)
8905 return posix_error();
8906 Py_RETURN_NONE;
8907}
8908#endif
8909
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911/*[clinic input]
8912os.fstat
8913
8914 fd : int
8915
8916Perform a stat system call on the given file descriptor.
8917
8918Like stat(), but for an open file descriptor.
8919Equivalent to os.stat(fd).
8920[clinic start generated code]*/
8921
Larry Hastings2f936352014-08-05 14:04:04 +10008922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008923os_fstat_impl(PyObject *module, int fd)
8924/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008925{
Victor Stinner8c62be82010-05-06 00:08:46 +00008926 STRUCT_STAT st;
8927 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008928 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008929
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008930 do {
8931 Py_BEGIN_ALLOW_THREADS
8932 res = FSTAT(fd, &st);
8933 Py_END_ALLOW_THREADS
8934 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008936#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008937 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008938#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008939 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008940#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008941 }
Tim Peters5aa91602002-01-30 05:46:57 +00008942
Victor Stinner4195b5c2012-02-08 23:03:19 +01008943 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008944}
8945
Larry Hastings2f936352014-08-05 14:04:04 +10008946
8947/*[clinic input]
8948os.isatty -> bool
8949 fd: int
8950 /
8951
8952Return True if the fd is connected to a terminal.
8953
8954Return True if the file descriptor is an open file descriptor
8955connected to the slave end of a terminal.
8956[clinic start generated code]*/
8957
Larry Hastings2f936352014-08-05 14:04:04 +10008958static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008959os_isatty_impl(PyObject *module, int fd)
8960/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008961{
Steve Dower8fc89802015-04-12 00:26:27 -04008962 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008963 _Py_BEGIN_SUPPRESS_IPH
8964 return_value = isatty(fd);
8965 _Py_END_SUPPRESS_IPH
8966 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008967}
8968
8969
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008970#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008971/*[clinic input]
8972os.pipe
8973
8974Create a pipe.
8975
8976Returns a tuple of two file descriptors:
8977 (read_fd, write_fd)
8978[clinic start generated code]*/
8979
Larry Hastings2f936352014-08-05 14:04:04 +10008980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008981os_pipe_impl(PyObject *module)
8982/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008983{
Victor Stinner8c62be82010-05-06 00:08:46 +00008984 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008985#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008987 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008989#else
8990 int res;
8991#endif
8992
8993#ifdef MS_WINDOWS
8994 attr.nLength = sizeof(attr);
8995 attr.lpSecurityDescriptor = NULL;
8996 attr.bInheritHandle = FALSE;
8997
8998 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008999 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009000 ok = CreatePipe(&read, &write, &attr, 0);
9001 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009002 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9003 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009004 if (fds[0] == -1 || fds[1] == -1) {
9005 CloseHandle(read);
9006 CloseHandle(write);
9007 ok = 0;
9008 }
9009 }
Steve Dowerc3630612016-11-19 18:41:16 -08009010 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009011 Py_END_ALLOW_THREADS
9012
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009014 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009015#else
9016
9017#ifdef HAVE_PIPE2
9018 Py_BEGIN_ALLOW_THREADS
9019 res = pipe2(fds, O_CLOEXEC);
9020 Py_END_ALLOW_THREADS
9021
9022 if (res != 0 && errno == ENOSYS)
9023 {
9024#endif
9025 Py_BEGIN_ALLOW_THREADS
9026 res = pipe(fds);
9027 Py_END_ALLOW_THREADS
9028
9029 if (res == 0) {
9030 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9031 close(fds[0]);
9032 close(fds[1]);
9033 return NULL;
9034 }
9035 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9036 close(fds[0]);
9037 close(fds[1]);
9038 return NULL;
9039 }
9040 }
9041#ifdef HAVE_PIPE2
9042 }
9043#endif
9044
9045 if (res != 0)
9046 return PyErr_SetFromErrno(PyExc_OSError);
9047#endif /* !MS_WINDOWS */
9048 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009049}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009050#endif /* HAVE_PIPE */
9051
Larry Hastings2f936352014-08-05 14:04:04 +10009052
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009053#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009054/*[clinic input]
9055os.pipe2
9056
9057 flags: int
9058 /
9059
9060Create a pipe with flags set atomically.
9061
9062Returns a tuple of two file descriptors:
9063 (read_fd, write_fd)
9064
9065flags can be constructed by ORing together one or more of these values:
9066O_NONBLOCK, O_CLOEXEC.
9067[clinic start generated code]*/
9068
Larry Hastings2f936352014-08-05 14:04:04 +10009069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009070os_pipe2_impl(PyObject *module, int flags)
9071/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009072{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009073 int fds[2];
9074 int res;
9075
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009076 res = pipe2(fds, flags);
9077 if (res != 0)
9078 return posix_error();
9079 return Py_BuildValue("(ii)", fds[0], fds[1]);
9080}
9081#endif /* HAVE_PIPE2 */
9082
Larry Hastings2f936352014-08-05 14:04:04 +10009083
Ross Lagerwall7807c352011-03-17 20:20:30 +02009084#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009085/*[clinic input]
9086os.writev -> Py_ssize_t
9087 fd: int
9088 buffers: object
9089 /
9090
9091Iterate over buffers, and write the contents of each to a file descriptor.
9092
9093Returns the total number of bytes written.
9094buffers must be a sequence of bytes-like objects.
9095[clinic start generated code]*/
9096
Larry Hastings2f936352014-08-05 14:04:04 +10009097static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009098os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9099/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009100{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009101 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009102 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009103 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009104 struct iovec *iov;
9105 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009106
9107 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009108 PyErr_SetString(PyExc_TypeError,
9109 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009110 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009111 }
Larry Hastings2f936352014-08-05 14:04:04 +10009112 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009113 if (cnt < 0)
9114 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009115
Larry Hastings2f936352014-08-05 14:04:04 +10009116 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9117 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009118 }
9119
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009120 do {
9121 Py_BEGIN_ALLOW_THREADS
9122 result = writev(fd, iov, cnt);
9123 Py_END_ALLOW_THREADS
9124 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009125
9126 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009127 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009128 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009129
Georg Brandl306336b2012-06-24 12:55:33 +02009130 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009131}
Larry Hastings2f936352014-08-05 14:04:04 +10009132#endif /* HAVE_WRITEV */
9133
9134
9135#ifdef HAVE_PWRITE
9136/*[clinic input]
9137os.pwrite -> Py_ssize_t
9138
9139 fd: int
9140 buffer: Py_buffer
9141 offset: Py_off_t
9142 /
9143
9144Write bytes to a file descriptor starting at a particular offset.
9145
9146Write buffer to fd, starting at offset bytes from the beginning of
9147the file. Returns the number of bytes writte. Does not change the
9148current file offset.
9149[clinic start generated code]*/
9150
Larry Hastings2f936352014-08-05 14:04:04 +10009151static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009152os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9153/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009154{
9155 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009156 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009157
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009158 do {
9159 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009160 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009161 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009162 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009163 Py_END_ALLOW_THREADS
9164 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009165
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009166 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009167 posix_error();
9168 return size;
9169}
9170#endif /* HAVE_PWRITE */
9171
Pablo Galindo4defba32018-01-27 16:16:37 +00009172#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9173/*[clinic input]
9174os.pwritev -> Py_ssize_t
9175
9176 fd: int
9177 buffers: object
9178 offset: Py_off_t
9179 flags: int = 0
9180 /
9181
9182Writes the contents of bytes-like objects to a file descriptor at a given offset.
9183
9184Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9185of bytes-like objects. Buffers are processed in array order. Entire contents of first
9186buffer is written before proceeding to second, and so on. The operating system may
9187set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9188This function writes the contents of each object to the file descriptor and returns
9189the total number of bytes written.
9190
9191The flags argument contains a bitwise OR of zero or more of the following flags:
9192
9193- RWF_DSYNC
9194- RWF_SYNC
9195
9196Using non-zero flags requires Linux 4.7 or newer.
9197[clinic start generated code]*/
9198
9199static Py_ssize_t
9200os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9201 int flags)
9202/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9203{
9204 Py_ssize_t cnt;
9205 Py_ssize_t result;
9206 int async_err = 0;
9207 struct iovec *iov;
9208 Py_buffer *buf;
9209
9210 if (!PySequence_Check(buffers)) {
9211 PyErr_SetString(PyExc_TypeError,
9212 "pwritev() arg 2 must be a sequence");
9213 return -1;
9214 }
9215
9216 cnt = PySequence_Size(buffers);
9217 if (cnt < 0) {
9218 return -1;
9219 }
9220
9221#ifndef HAVE_PWRITEV2
9222 if(flags != 0) {
9223 argument_unavailable_error("pwritev2", "flags");
9224 return -1;
9225 }
9226#endif
9227
9228 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9229 return -1;
9230 }
9231#ifdef HAVE_PWRITEV2
9232 do {
9233 Py_BEGIN_ALLOW_THREADS
9234 _Py_BEGIN_SUPPRESS_IPH
9235 result = pwritev2(fd, iov, cnt, offset, flags);
9236 _Py_END_SUPPRESS_IPH
9237 Py_END_ALLOW_THREADS
9238 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9239#else
9240 do {
9241 Py_BEGIN_ALLOW_THREADS
9242 _Py_BEGIN_SUPPRESS_IPH
9243 result = pwritev(fd, iov, cnt, offset);
9244 _Py_END_SUPPRESS_IPH
9245 Py_END_ALLOW_THREADS
9246 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9247#endif
9248
9249 iov_cleanup(iov, buf, cnt);
9250 if (result < 0) {
9251 if (!async_err) {
9252 posix_error();
9253 }
9254 return -1;
9255 }
9256
9257 return result;
9258}
9259#endif /* HAVE_PWRITEV */
9260
9261
9262
Larry Hastings2f936352014-08-05 14:04:04 +10009263
9264#ifdef HAVE_MKFIFO
9265/*[clinic input]
9266os.mkfifo
9267
9268 path: path_t
9269 mode: int=0o666
9270 *
9271 dir_fd: dir_fd(requires='mkfifoat')=None
9272
9273Create a "fifo" (a POSIX named pipe).
9274
9275If dir_fd is not None, it should be a file descriptor open to a directory,
9276 and path should be relative; path will then be relative to that directory.
9277dir_fd may not be implemented on your platform.
9278 If it is unavailable, using it will raise a NotImplementedError.
9279[clinic start generated code]*/
9280
Larry Hastings2f936352014-08-05 14:04:04 +10009281static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009282os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9283/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009284{
9285 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009286 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009287
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009288 do {
9289 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009290#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009291 if (dir_fd != DEFAULT_DIR_FD)
9292 result = mkfifoat(dir_fd, path->narrow, mode);
9293 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009294#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009295 result = mkfifo(path->narrow, mode);
9296 Py_END_ALLOW_THREADS
9297 } while (result != 0 && errno == EINTR &&
9298 !(async_err = PyErr_CheckSignals()));
9299 if (result != 0)
9300 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009301
9302 Py_RETURN_NONE;
9303}
9304#endif /* HAVE_MKFIFO */
9305
9306
9307#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9308/*[clinic input]
9309os.mknod
9310
9311 path: path_t
9312 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009313 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009314 *
9315 dir_fd: dir_fd(requires='mknodat')=None
9316
9317Create a node in the file system.
9318
9319Create a node in the file system (file, device special file or named pipe)
9320at path. mode specifies both the permissions to use and the
9321type of node to be created, being combined (bitwise OR) with one of
9322S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9323device defines the newly created device special file (probably using
9324os.makedev()). Otherwise device is ignored.
9325
9326If dir_fd is not None, it should be a file descriptor open to a directory,
9327 and path should be relative; path will then be relative to that directory.
9328dir_fd may not be implemented on your platform.
9329 If it is unavailable, using it will raise a NotImplementedError.
9330[clinic start generated code]*/
9331
Larry Hastings2f936352014-08-05 14:04:04 +10009332static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009333os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009334 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009335/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009336{
9337 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009338 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009339
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009340 do {
9341 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009342#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009343 if (dir_fd != DEFAULT_DIR_FD)
9344 result = mknodat(dir_fd, path->narrow, mode, device);
9345 else
Larry Hastings2f936352014-08-05 14:04:04 +10009346#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009347 result = mknod(path->narrow, mode, device);
9348 Py_END_ALLOW_THREADS
9349 } while (result != 0 && errno == EINTR &&
9350 !(async_err = PyErr_CheckSignals()));
9351 if (result != 0)
9352 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009353
9354 Py_RETURN_NONE;
9355}
9356#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9357
9358
9359#ifdef HAVE_DEVICE_MACROS
9360/*[clinic input]
9361os.major -> unsigned_int
9362
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009363 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009364 /
9365
9366Extracts a device major number from a raw device number.
9367[clinic start generated code]*/
9368
Larry Hastings2f936352014-08-05 14:04:04 +10009369static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009370os_major_impl(PyObject *module, dev_t device)
9371/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009372{
9373 return major(device);
9374}
9375
9376
9377/*[clinic input]
9378os.minor -> unsigned_int
9379
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009380 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009381 /
9382
9383Extracts a device minor number from a raw device number.
9384[clinic start generated code]*/
9385
Larry Hastings2f936352014-08-05 14:04:04 +10009386static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009387os_minor_impl(PyObject *module, dev_t device)
9388/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009389{
9390 return minor(device);
9391}
9392
9393
9394/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009395os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009396
9397 major: int
9398 minor: int
9399 /
9400
9401Composes a raw device number from the major and minor device numbers.
9402[clinic start generated code]*/
9403
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009404static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009405os_makedev_impl(PyObject *module, int major, int minor)
9406/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009407{
9408 return makedev(major, minor);
9409}
9410#endif /* HAVE_DEVICE_MACROS */
9411
9412
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009413#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009414/*[clinic input]
9415os.ftruncate
9416
9417 fd: int
9418 length: Py_off_t
9419 /
9420
9421Truncate a file, specified by file descriptor, to a specific length.
9422[clinic start generated code]*/
9423
Larry Hastings2f936352014-08-05 14:04:04 +10009424static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009425os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9426/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009427{
9428 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009429 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009430
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009431 do {
9432 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009433 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009434#ifdef MS_WINDOWS
9435 result = _chsize_s(fd, length);
9436#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009437 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009438#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009439 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009440 Py_END_ALLOW_THREADS
9441 } while (result != 0 && errno == EINTR &&
9442 !(async_err = PyErr_CheckSignals()));
9443 if (result != 0)
9444 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009445 Py_RETURN_NONE;
9446}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009447#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009448
9449
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009450#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009451/*[clinic input]
9452os.truncate
9453 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9454 length: Py_off_t
9455
9456Truncate a file, specified by path, to a specific length.
9457
9458On some platforms, path may also be specified as an open file descriptor.
9459 If this functionality is unavailable, using it raises an exception.
9460[clinic start generated code]*/
9461
Larry Hastings2f936352014-08-05 14:04:04 +10009462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009463os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9464/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009465{
9466 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009467#ifdef MS_WINDOWS
9468 int fd;
9469#endif
9470
9471 if (path->fd != -1)
9472 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009473
9474 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009475 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009476#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009477 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009478 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009479 result = -1;
9480 else {
9481 result = _chsize_s(fd, length);
9482 close(fd);
9483 if (result < 0)
9484 errno = result;
9485 }
9486#else
9487 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009488#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009489 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009490 Py_END_ALLOW_THREADS
9491 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009492 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009493
9494 Py_RETURN_NONE;
9495}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009496#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009497
Ross Lagerwall7807c352011-03-17 20:20:30 +02009498
Victor Stinnerd6b17692014-09-30 12:20:05 +02009499/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9500 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9501 defined, which is the case in Python on AIX. AIX bug report:
9502 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9503#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9504# define POSIX_FADVISE_AIX_BUG
9505#endif
9506
Victor Stinnerec39e262014-09-30 12:35:58 +02009507
Victor Stinnerd6b17692014-09-30 12:20:05 +02009508#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009509/*[clinic input]
9510os.posix_fallocate
9511
9512 fd: int
9513 offset: Py_off_t
9514 length: Py_off_t
9515 /
9516
9517Ensure a file has allocated at least a particular number of bytes on disk.
9518
9519Ensure that the file specified by fd encompasses a range of bytes
9520starting at offset bytes from the beginning and continuing for length bytes.
9521[clinic start generated code]*/
9522
Larry Hastings2f936352014-08-05 14:04:04 +10009523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009524os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009525 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009526/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009527{
9528 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009529 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009530
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009531 do {
9532 Py_BEGIN_ALLOW_THREADS
9533 result = posix_fallocate(fd, offset, length);
9534 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009535 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9536
9537 if (result == 0)
9538 Py_RETURN_NONE;
9539
9540 if (async_err)
9541 return NULL;
9542
9543 errno = result;
9544 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009545}
Victor Stinnerec39e262014-09-30 12:35:58 +02009546#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009547
Ross Lagerwall7807c352011-03-17 20:20:30 +02009548
Victor Stinnerd6b17692014-09-30 12:20:05 +02009549#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009550/*[clinic input]
9551os.posix_fadvise
9552
9553 fd: int
9554 offset: Py_off_t
9555 length: Py_off_t
9556 advice: int
9557 /
9558
9559Announce an intention to access data in a specific pattern.
9560
9561Announce an intention to access data in a specific pattern, thus allowing
9562the kernel to make optimizations.
9563The advice applies to the region of the file specified by fd starting at
9564offset and continuing for length bytes.
9565advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9566POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9567POSIX_FADV_DONTNEED.
9568[clinic start generated code]*/
9569
Larry Hastings2f936352014-08-05 14:04:04 +10009570static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009571os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009572 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009573/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009574{
9575 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009576 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009577
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009578 do {
9579 Py_BEGIN_ALLOW_THREADS
9580 result = posix_fadvise(fd, offset, length, advice);
9581 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009582 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9583
9584 if (result == 0)
9585 Py_RETURN_NONE;
9586
9587 if (async_err)
9588 return NULL;
9589
9590 errno = result;
9591 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009592}
Victor Stinnerec39e262014-09-30 12:35:58 +02009593#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009594
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009595#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009596
Fred Drake762e2061999-08-26 17:23:54 +00009597/* Save putenv() parameters as values here, so we can collect them when they
9598 * get re-set with another call for the same key. */
9599static PyObject *posix_putenv_garbage;
9600
Larry Hastings2f936352014-08-05 14:04:04 +10009601static void
9602posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009603{
Larry Hastings2f936352014-08-05 14:04:04 +10009604 /* Install the first arg and newstr in posix_putenv_garbage;
9605 * this will cause previous value to be collected. This has to
9606 * happen after the real putenv() call because the old value
9607 * was still accessible until then. */
9608 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9609 /* really not much we can do; just leak */
9610 PyErr_Clear();
9611 else
9612 Py_DECREF(value);
9613}
9614
9615
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009616#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009617/*[clinic input]
9618os.putenv
9619
9620 name: unicode
9621 value: unicode
9622 /
9623
9624Change or add an environment variable.
9625[clinic start generated code]*/
9626
Larry Hastings2f936352014-08-05 14:04:04 +10009627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009628os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9629/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009630{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009631 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009632 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009633
Serhiy Storchaka77703942017-06-25 07:33:01 +03009634 /* Search from index 1 because on Windows starting '=' is allowed for
9635 defining hidden environment variables. */
9636 if (PyUnicode_GET_LENGTH(name) == 0 ||
9637 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9638 {
9639 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9640 return NULL;
9641 }
Larry Hastings2f936352014-08-05 14:04:04 +10009642 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9643 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009644 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009645 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009646
9647 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9648 if (env == NULL)
9649 goto error;
9650 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009651 PyErr_Format(PyExc_ValueError,
9652 "the environment variable is longer than %u characters",
9653 _MAX_ENV);
9654 goto error;
9655 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009656 if (wcslen(env) != (size_t)size) {
9657 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009658 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009659 }
9660
Larry Hastings2f936352014-08-05 14:04:04 +10009661 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009663 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009665
Larry Hastings2f936352014-08-05 14:04:04 +10009666 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009667 Py_RETURN_NONE;
9668
9669error:
Larry Hastings2f936352014-08-05 14:04:04 +10009670 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009671 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009672}
Larry Hastings2f936352014-08-05 14:04:04 +10009673#else /* MS_WINDOWS */
9674/*[clinic input]
9675os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009676
Larry Hastings2f936352014-08-05 14:04:04 +10009677 name: FSConverter
9678 value: FSConverter
9679 /
9680
9681Change or add an environment variable.
9682[clinic start generated code]*/
9683
Larry Hastings2f936352014-08-05 14:04:04 +10009684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009685os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9686/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009687{
9688 PyObject *bytes = NULL;
9689 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009690 const char *name_string = PyBytes_AS_STRING(name);
9691 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009692
Serhiy Storchaka77703942017-06-25 07:33:01 +03009693 if (strchr(name_string, '=') != NULL) {
9694 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9695 return NULL;
9696 }
Larry Hastings2f936352014-08-05 14:04:04 +10009697 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9698 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009699 return NULL;
9700 }
9701
9702 env = PyBytes_AS_STRING(bytes);
9703 if (putenv(env)) {
9704 Py_DECREF(bytes);
9705 return posix_error();
9706 }
9707
9708 posix_putenv_garbage_setitem(name, bytes);
9709 Py_RETURN_NONE;
9710}
9711#endif /* MS_WINDOWS */
9712#endif /* HAVE_PUTENV */
9713
9714
9715#ifdef HAVE_UNSETENV
9716/*[clinic input]
9717os.unsetenv
9718 name: FSConverter
9719 /
9720
9721Delete an environment variable.
9722[clinic start generated code]*/
9723
Larry Hastings2f936352014-08-05 14:04:04 +10009724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009725os_unsetenv_impl(PyObject *module, PyObject *name)
9726/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009727{
Victor Stinner984890f2011-11-24 13:53:38 +01009728#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009729 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009730#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009731
Victor Stinner984890f2011-11-24 13:53:38 +01009732#ifdef HAVE_BROKEN_UNSETENV
9733 unsetenv(PyBytes_AS_STRING(name));
9734#else
Victor Stinner65170952011-11-22 22:16:17 +01009735 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009736 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009737 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009738#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009739
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 /* Remove the key from posix_putenv_garbage;
9741 * this will cause it to be collected. This has to
9742 * happen after the real unsetenv() call because the
9743 * old value was still accessible until then.
9744 */
Victor Stinner65170952011-11-22 22:16:17 +01009745 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 /* really not much we can do; just leak */
9747 PyErr_Clear();
9748 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009749 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009750}
Larry Hastings2f936352014-08-05 14:04:04 +10009751#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009752
Larry Hastings2f936352014-08-05 14:04:04 +10009753
9754/*[clinic input]
9755os.strerror
9756
9757 code: int
9758 /
9759
9760Translate an error code to a message string.
9761[clinic start generated code]*/
9762
Larry Hastings2f936352014-08-05 14:04:04 +10009763static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009764os_strerror_impl(PyObject *module, int code)
9765/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009766{
9767 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 if (message == NULL) {
9769 PyErr_SetString(PyExc_ValueError,
9770 "strerror() argument out of range");
9771 return NULL;
9772 }
Victor Stinner1b579672011-12-17 05:47:23 +01009773 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009774}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009775
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009776
Guido van Rossumc9641791998-08-04 15:26:23 +00009777#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009778#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009779/*[clinic input]
9780os.WCOREDUMP -> bool
9781
9782 status: int
9783 /
9784
9785Return True if the process returning status was dumped to a core file.
9786[clinic start generated code]*/
9787
Larry Hastings2f936352014-08-05 14:04:04 +10009788static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009789os_WCOREDUMP_impl(PyObject *module, int status)
9790/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009791{
9792 WAIT_TYPE wait_status;
9793 WAIT_STATUS_INT(wait_status) = status;
9794 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009795}
9796#endif /* WCOREDUMP */
9797
Larry Hastings2f936352014-08-05 14:04:04 +10009798
Fred Drake106c1a02002-04-23 15:58:02 +00009799#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009800/*[clinic input]
9801os.WIFCONTINUED -> bool
9802
9803 status: int
9804
9805Return True if a particular process was continued from a job control stop.
9806
9807Return True if the process returning status was continued from a
9808job control stop.
9809[clinic start generated code]*/
9810
Larry Hastings2f936352014-08-05 14:04:04 +10009811static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009812os_WIFCONTINUED_impl(PyObject *module, int status)
9813/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009814{
9815 WAIT_TYPE wait_status;
9816 WAIT_STATUS_INT(wait_status) = status;
9817 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009818}
9819#endif /* WIFCONTINUED */
9820
Larry Hastings2f936352014-08-05 14:04:04 +10009821
Guido van Rossumc9641791998-08-04 15:26:23 +00009822#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009823/*[clinic input]
9824os.WIFSTOPPED -> bool
9825
9826 status: int
9827
9828Return True if the process returning status was stopped.
9829[clinic start generated code]*/
9830
Larry Hastings2f936352014-08-05 14:04:04 +10009831static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009832os_WIFSTOPPED_impl(PyObject *module, int status)
9833/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009834{
9835 WAIT_TYPE wait_status;
9836 WAIT_STATUS_INT(wait_status) = status;
9837 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009838}
9839#endif /* WIFSTOPPED */
9840
Larry Hastings2f936352014-08-05 14:04:04 +10009841
Guido van Rossumc9641791998-08-04 15:26:23 +00009842#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009843/*[clinic input]
9844os.WIFSIGNALED -> bool
9845
9846 status: int
9847
9848Return True if the process returning status was terminated by a signal.
9849[clinic start generated code]*/
9850
Larry Hastings2f936352014-08-05 14:04:04 +10009851static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009852os_WIFSIGNALED_impl(PyObject *module, int status)
9853/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009854{
9855 WAIT_TYPE wait_status;
9856 WAIT_STATUS_INT(wait_status) = status;
9857 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009858}
9859#endif /* WIFSIGNALED */
9860
Larry Hastings2f936352014-08-05 14:04:04 +10009861
Guido van Rossumc9641791998-08-04 15:26:23 +00009862#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009863/*[clinic input]
9864os.WIFEXITED -> bool
9865
9866 status: int
9867
9868Return True if the process returning status exited via the exit() system call.
9869[clinic start generated code]*/
9870
Larry Hastings2f936352014-08-05 14:04:04 +10009871static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009872os_WIFEXITED_impl(PyObject *module, int status)
9873/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009874{
9875 WAIT_TYPE wait_status;
9876 WAIT_STATUS_INT(wait_status) = status;
9877 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009878}
9879#endif /* WIFEXITED */
9880
Larry Hastings2f936352014-08-05 14:04:04 +10009881
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009882#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009883/*[clinic input]
9884os.WEXITSTATUS -> int
9885
9886 status: int
9887
9888Return the process return code from status.
9889[clinic start generated code]*/
9890
Larry Hastings2f936352014-08-05 14:04:04 +10009891static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009892os_WEXITSTATUS_impl(PyObject *module, int status)
9893/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009894{
9895 WAIT_TYPE wait_status;
9896 WAIT_STATUS_INT(wait_status) = status;
9897 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009898}
9899#endif /* WEXITSTATUS */
9900
Larry Hastings2f936352014-08-05 14:04:04 +10009901
Guido van Rossumc9641791998-08-04 15:26:23 +00009902#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009903/*[clinic input]
9904os.WTERMSIG -> int
9905
9906 status: int
9907
9908Return the signal that terminated the process that provided the status value.
9909[clinic start generated code]*/
9910
Larry Hastings2f936352014-08-05 14:04:04 +10009911static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009912os_WTERMSIG_impl(PyObject *module, int status)
9913/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009914{
9915 WAIT_TYPE wait_status;
9916 WAIT_STATUS_INT(wait_status) = status;
9917 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009918}
9919#endif /* WTERMSIG */
9920
Larry Hastings2f936352014-08-05 14:04:04 +10009921
Guido van Rossumc9641791998-08-04 15:26:23 +00009922#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009923/*[clinic input]
9924os.WSTOPSIG -> int
9925
9926 status: int
9927
9928Return the signal that stopped the process that provided the status value.
9929[clinic start generated code]*/
9930
Larry Hastings2f936352014-08-05 14:04:04 +10009931static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009932os_WSTOPSIG_impl(PyObject *module, int status)
9933/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009934{
9935 WAIT_TYPE wait_status;
9936 WAIT_STATUS_INT(wait_status) = status;
9937 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009938}
9939#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009940#endif /* HAVE_SYS_WAIT_H */
9941
9942
Thomas Wouters477c8d52006-05-27 19:21:47 +00009943#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009944#ifdef _SCO_DS
9945/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9946 needed definitions in sys/statvfs.h */
9947#define _SVID3
9948#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009949#include <sys/statvfs.h>
9950
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009951static PyObject*
9952_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -08009953 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 if (v == NULL)
9955 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009956
9957#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9959 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9960 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9961 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9962 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9963 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9964 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9965 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9966 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9967 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009968#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9970 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9971 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009972 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009974 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009976 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009978 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009980 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009982 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9984 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009985#endif
Michael Felt502d5512018-01-05 13:01:58 +01009986/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9987 * (issue #32390). */
9988#if defined(_AIX) && defined(_ALL_SOURCE)
9989 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9990#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009991 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009992#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009993 if (PyErr_Occurred()) {
9994 Py_DECREF(v);
9995 return NULL;
9996 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009997
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009999}
10000
Larry Hastings2f936352014-08-05 14:04:04 +100010001
10002/*[clinic input]
10003os.fstatvfs
10004 fd: int
10005 /
10006
10007Perform an fstatvfs system call on the given fd.
10008
10009Equivalent to statvfs(fd).
10010[clinic start generated code]*/
10011
Larry Hastings2f936352014-08-05 14:04:04 +100010012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010013os_fstatvfs_impl(PyObject *module, int fd)
10014/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010015{
10016 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010017 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010019
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010020 do {
10021 Py_BEGIN_ALLOW_THREADS
10022 result = fstatvfs(fd, &st);
10023 Py_END_ALLOW_THREADS
10024 } while (result != 0 && errno == EINTR &&
10025 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010026 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010027 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010028
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010030}
Larry Hastings2f936352014-08-05 14:04:04 +100010031#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010032
10033
Thomas Wouters477c8d52006-05-27 19:21:47 +000010034#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010035#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010036/*[clinic input]
10037os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010038
Larry Hastings2f936352014-08-05 14:04:04 +100010039 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10040
10041Perform a statvfs system call on the given path.
10042
10043path may always be specified as a string.
10044On some platforms, path may also be specified as an open file descriptor.
10045 If this functionality is unavailable, using it raises an exception.
10046[clinic start generated code]*/
10047
Larry Hastings2f936352014-08-05 14:04:04 +100010048static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010049os_statvfs_impl(PyObject *module, path_t *path)
10050/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010051{
10052 int result;
10053 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010054
10055 Py_BEGIN_ALLOW_THREADS
10056#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010057 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010058#ifdef __APPLE__
10059 /* handle weak-linking on Mac OS X 10.3 */
10060 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010061 fd_specified("statvfs", path->fd);
10062 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010063 }
10064#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010065 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010066 }
10067 else
10068#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010069 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010070 Py_END_ALLOW_THREADS
10071
10072 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010073 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010074 }
10075
Larry Hastings2f936352014-08-05 14:04:04 +100010076 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010077}
Larry Hastings2f936352014-08-05 14:04:04 +100010078#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10079
Guido van Rossum94f6f721999-01-06 18:42:14 +000010080
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010081#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010082/*[clinic input]
10083os._getdiskusage
10084
Steve Dower23ad6d02018-02-22 10:39:10 -080010085 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010086
10087Return disk usage statistics about the given path as a (total, free) tuple.
10088[clinic start generated code]*/
10089
Larry Hastings2f936352014-08-05 14:04:04 +100010090static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010091os__getdiskusage_impl(PyObject *module, path_t *path)
10092/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010093{
10094 BOOL retval;
10095 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010096 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010097
10098 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010099 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010100 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010101 if (retval == 0) {
10102 if (GetLastError() == ERROR_DIRECTORY) {
10103 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010104
Joe Pamerc8c02492018-09-25 10:57:36 -040010105 dir_path = PyMem_New(wchar_t, path->length + 1);
10106 if (dir_path == NULL) {
10107 return PyErr_NoMemory();
10108 }
10109
10110 wcscpy_s(dir_path, path->length + 1, path->wide);
10111
10112 if (_dirnameW(dir_path) != -1) {
10113 Py_BEGIN_ALLOW_THREADS
10114 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10115 Py_END_ALLOW_THREADS
10116 }
10117 /* Record the last error in case it's modified by PyMem_Free. */
10118 err = GetLastError();
10119 PyMem_Free(dir_path);
10120 if (retval) {
10121 goto success;
10122 }
10123 }
10124 return PyErr_SetFromWindowsErr(err);
10125 }
10126
10127success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010128 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10129}
Larry Hastings2f936352014-08-05 14:04:04 +100010130#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010131
10132
Fred Drakec9680921999-12-13 16:37:25 +000010133/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10134 * It maps strings representing configuration variable names to
10135 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010136 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010137 * rarely-used constants. There are three separate tables that use
10138 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010139 *
10140 * This code is always included, even if none of the interfaces that
10141 * need it are included. The #if hackery needed to avoid it would be
10142 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010143 */
10144struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010145 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010146 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010147};
10148
Fred Drake12c6e2d1999-12-14 21:25:03 +000010149static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010150conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010151 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010152{
Christian Heimes217cfd12007-12-02 14:31:20 +000010153 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010154 int value = _PyLong_AsInt(arg);
10155 if (value == -1 && PyErr_Occurred())
10156 return 0;
10157 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010158 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010159 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010160 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010161 /* look up the value in the table using a binary search */
10162 size_t lo = 0;
10163 size_t mid;
10164 size_t hi = tablesize;
10165 int cmp;
10166 const char *confname;
10167 if (!PyUnicode_Check(arg)) {
10168 PyErr_SetString(PyExc_TypeError,
10169 "configuration names must be strings or integers");
10170 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010172 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010173 if (confname == NULL)
10174 return 0;
10175 while (lo < hi) {
10176 mid = (lo + hi) / 2;
10177 cmp = strcmp(confname, table[mid].name);
10178 if (cmp < 0)
10179 hi = mid;
10180 else if (cmp > 0)
10181 lo = mid + 1;
10182 else {
10183 *valuep = table[mid].value;
10184 return 1;
10185 }
10186 }
10187 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10188 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010190}
10191
10192
10193#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10194static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010195#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010197#endif
10198#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010200#endif
Fred Drakec9680921999-12-13 16:37:25 +000010201#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010246#ifdef _PC_ACL_ENABLED
10247 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10248#endif
10249#ifdef _PC_MIN_HOLE_SIZE
10250 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10251#endif
10252#ifdef _PC_ALLOC_SIZE_MIN
10253 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10254#endif
10255#ifdef _PC_REC_INCR_XFER_SIZE
10256 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10257#endif
10258#ifdef _PC_REC_MAX_XFER_SIZE
10259 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10260#endif
10261#ifdef _PC_REC_MIN_XFER_SIZE
10262 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10263#endif
10264#ifdef _PC_REC_XFER_ALIGN
10265 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10266#endif
10267#ifdef _PC_SYMLINK_MAX
10268 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10269#endif
10270#ifdef _PC_XATTR_ENABLED
10271 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10272#endif
10273#ifdef _PC_XATTR_EXISTS
10274 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10275#endif
10276#ifdef _PC_TIMESTAMP_RESOLUTION
10277 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10278#endif
Fred Drakec9680921999-12-13 16:37:25 +000010279};
10280
Fred Drakec9680921999-12-13 16:37:25 +000010281static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010282conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010283{
10284 return conv_confname(arg, valuep, posix_constants_pathconf,
10285 sizeof(posix_constants_pathconf)
10286 / sizeof(struct constdef));
10287}
10288#endif
10289
Larry Hastings2f936352014-08-05 14:04:04 +100010290
Fred Drakec9680921999-12-13 16:37:25 +000010291#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010292/*[clinic input]
10293os.fpathconf -> long
10294
10295 fd: int
10296 name: path_confname
10297 /
10298
10299Return the configuration limit name for the file descriptor fd.
10300
10301If there is no limit, return -1.
10302[clinic start generated code]*/
10303
Larry Hastings2f936352014-08-05 14:04:04 +100010304static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010305os_fpathconf_impl(PyObject *module, int fd, int name)
10306/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010307{
10308 long limit;
10309
10310 errno = 0;
10311 limit = fpathconf(fd, name);
10312 if (limit == -1 && errno != 0)
10313 posix_error();
10314
10315 return limit;
10316}
10317#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010318
10319
10320#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010321/*[clinic input]
10322os.pathconf -> long
10323 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10324 name: path_confname
10325
10326Return the configuration limit name for the file or directory path.
10327
10328If there is no limit, return -1.
10329On some platforms, path may also be specified as an open file descriptor.
10330 If this functionality is unavailable, using it raises an exception.
10331[clinic start generated code]*/
10332
Larry Hastings2f936352014-08-05 14:04:04 +100010333static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010334os_pathconf_impl(PyObject *module, path_t *path, int name)
10335/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010336{
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010338
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010340#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010341 if (path->fd != -1)
10342 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010343 else
10344#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010345 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 if (limit == -1 && errno != 0) {
10347 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010348 /* could be a path or name problem */
10349 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010350 else
Larry Hastings2f936352014-08-05 14:04:04 +100010351 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 }
Larry Hastings2f936352014-08-05 14:04:04 +100010353
10354 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010355}
Larry Hastings2f936352014-08-05 14:04:04 +100010356#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010357
10358#ifdef HAVE_CONFSTR
10359static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010360#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010362#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010363#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010365#endif
10366#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010368#endif
Fred Draked86ed291999-12-15 15:34:33 +000010369#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010371#endif
10372#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010374#endif
10375#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010377#endif
10378#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010380#endif
Fred Drakec9680921999-12-13 16:37:25 +000010381#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
Fred Draked86ed291999-12-15 15:34:33 +000010405#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010407#endif
Fred Drakec9680921999-12-13 16:37:25 +000010408#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
Fred Draked86ed291999-12-15 15:34:33 +000010411#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010413#endif
10414#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010416#endif
10417#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010419#endif
10420#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010422#endif
Fred Drakec9680921999-12-13 16:37:25 +000010423#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010425#endif
10426#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010428#endif
10429#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010431#endif
10432#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010434#endif
10435#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010437#endif
10438#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010440#endif
10441#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010443#endif
10444#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010446#endif
10447#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010449#endif
10450#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010452#endif
10453#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010455#endif
10456#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010458#endif
10459#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010461#endif
10462#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010464#endif
10465#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010467#endif
10468#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010470#endif
Fred Draked86ed291999-12-15 15:34:33 +000010471#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010473#endif
10474#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010476#endif
10477#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010479#endif
10480#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010482#endif
10483#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010485#endif
10486#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010488#endif
10489#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010491#endif
10492#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010494#endif
10495#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010497#endif
10498#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010500#endif
10501#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010503#endif
10504#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010506#endif
10507#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010509#endif
Fred Drakec9680921999-12-13 16:37:25 +000010510};
10511
10512static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010513conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010514{
10515 return conv_confname(arg, valuep, posix_constants_confstr,
10516 sizeof(posix_constants_confstr)
10517 / sizeof(struct constdef));
10518}
10519
Larry Hastings2f936352014-08-05 14:04:04 +100010520
10521/*[clinic input]
10522os.confstr
10523
10524 name: confstr_confname
10525 /
10526
10527Return a string-valued system configuration variable.
10528[clinic start generated code]*/
10529
Larry Hastings2f936352014-08-05 14:04:04 +100010530static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010531os_confstr_impl(PyObject *module, int name)
10532/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010533{
10534 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010535 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010536 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010537
Victor Stinnercb043522010-09-10 23:49:04 +000010538 errno = 0;
10539 len = confstr(name, buffer, sizeof(buffer));
10540 if (len == 0) {
10541 if (errno) {
10542 posix_error();
10543 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010544 }
10545 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010546 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010547 }
10548 }
Victor Stinnercb043522010-09-10 23:49:04 +000010549
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010550 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010551 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010552 char *buf = PyMem_Malloc(len);
10553 if (buf == NULL)
10554 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010555 len2 = confstr(name, buf, len);
10556 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010557 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010558 PyMem_Free(buf);
10559 }
10560 else
10561 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010562 return result;
10563}
Larry Hastings2f936352014-08-05 14:04:04 +100010564#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010565
10566
10567#ifdef HAVE_SYSCONF
10568static struct constdef posix_constants_sysconf[] = {
10569#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010571#endif
10572#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010574#endif
10575#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010577#endif
10578#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010580#endif
10581#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010583#endif
10584#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010586#endif
10587#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010589#endif
10590#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010592#endif
10593#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010594 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010595#endif
10596#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010598#endif
Fred Draked86ed291999-12-15 15:34:33 +000010599#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010601#endif
10602#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010604#endif
Fred Drakec9680921999-12-13 16:37:25 +000010605#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010607#endif
Fred Drakec9680921999-12-13 16:37:25 +000010608#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010610#endif
10611#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010613#endif
10614#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010615 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010616#endif
10617#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010618 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010619#endif
10620#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010622#endif
Fred Draked86ed291999-12-15 15:34:33 +000010623#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010625#endif
Fred Drakec9680921999-12-13 16:37:25 +000010626#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010628#endif
10629#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010631#endif
10632#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010634#endif
10635#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010636 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010637#endif
10638#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010640#endif
Fred Draked86ed291999-12-15 15:34:33 +000010641#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010643#endif
Fred Drakec9680921999-12-13 16:37:25 +000010644#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010646#endif
10647#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010649#endif
10650#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010652#endif
10653#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010655#endif
10656#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010658#endif
10659#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010661#endif
10662#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010664#endif
10665#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010667#endif
10668#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010670#endif
10671#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010673#endif
10674#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010676#endif
10677#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
10680#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
10683#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010685#endif
10686#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
10689#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010691#endif
10692#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010694#endif
10695#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010697#endif
10698#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010700#endif
10701#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010703#endif
10704#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010706#endif
10707#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010709#endif
10710#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010712#endif
Fred Draked86ed291999-12-15 15:34:33 +000010713#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010715#endif
Fred Drakec9680921999-12-13 16:37:25 +000010716#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010718#endif
10719#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010721#endif
10722#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010724#endif
Fred Draked86ed291999-12-15 15:34:33 +000010725#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010727#endif
Fred Drakec9680921999-12-13 16:37:25 +000010728#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010730#endif
Fred Draked86ed291999-12-15 15:34:33 +000010731#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010733#endif
10734#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010736#endif
Fred Drakec9680921999-12-13 16:37:25 +000010737#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010739#endif
10740#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010742#endif
10743#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010745#endif
10746#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010748#endif
Fred Draked86ed291999-12-15 15:34:33 +000010749#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010751#endif
Fred Drakec9680921999-12-13 16:37:25 +000010752#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010754#endif
10755#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010757#endif
10758#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010760#endif
10761#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010763#endif
10764#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010766#endif
10767#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010769#endif
10770#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010772#endif
Fred Draked86ed291999-12-15 15:34:33 +000010773#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010775#endif
Fred Drakec9680921999-12-13 16:37:25 +000010776#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010778#endif
10779#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010781#endif
Fred Draked86ed291999-12-15 15:34:33 +000010782#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010784#endif
Fred Drakec9680921999-12-13 16:37:25 +000010785#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010787#endif
10788#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010790#endif
10791#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010793#endif
10794#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010795 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010796#endif
10797#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010798 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010799#endif
10800#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010802#endif
10803#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010805#endif
10806#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010808#endif
10809#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010811#endif
Fred Draked86ed291999-12-15 15:34:33 +000010812#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010814#endif
10815#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010817#endif
Fred Drakec9680921999-12-13 16:37:25 +000010818#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010820#endif
10821#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010823#endif
10824#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010826#endif
10827#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010829#endif
10830#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010832#endif
10833#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010835#endif
10836#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010838#endif
10839#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010841#endif
10842#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010844#endif
10845#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010847#endif
10848#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010850#endif
10851#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010853#endif
10854#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010856#endif
10857#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010859#endif
10860#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010862#endif
10863#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010865#endif
10866#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010868#endif
10869#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010871#endif
10872#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010874#endif
10875#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010877#endif
10878#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010880#endif
10881#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010883#endif
10884#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010886#endif
10887#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
10890#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
10893#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
10908#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010910#endif
10911#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010913#endif
10914#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010916#endif
10917#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010919#endif
10920#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010922#endif
Fred Draked86ed291999-12-15 15:34:33 +000010923#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010925#endif
Fred Drakec9680921999-12-13 16:37:25 +000010926#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010928#endif
10929#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010931#endif
10932#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010934#endif
10935#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
10938#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010940#endif
10941#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010943#endif
10944#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010946#endif
10947#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010949#endif
10950#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010952#endif
10953#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010955#endif
10956#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010958#endif
10959#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010961#endif
10962#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010964#endif
10965#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
10968#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010970#endif
10971#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010973#endif
10974#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010976#endif
10977#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010979#endif
10980#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010982#endif
10983#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010985#endif
10986#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010988#endif
10989#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010991#endif
10992#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010994#endif
10995#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010997#endif
10998#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011000#endif
11001#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011003#endif
11004#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011006#endif
11007#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011009#endif
11010#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011012#endif
11013#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011015#endif
11016#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011018#endif
11019#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011021#endif
11022#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011024#endif
11025#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011027#endif
11028#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011030#endif
11031#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011033#endif
11034#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011036#endif
11037#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011039#endif
11040#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011042#endif
11043#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011045#endif
11046#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011048#endif
11049#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011051#endif
11052#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011054#endif
11055#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011057#endif
11058#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011060#endif
11061};
11062
11063static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011064conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011065{
11066 return conv_confname(arg, valuep, posix_constants_sysconf,
11067 sizeof(posix_constants_sysconf)
11068 / sizeof(struct constdef));
11069}
11070
Larry Hastings2f936352014-08-05 14:04:04 +100011071
11072/*[clinic input]
11073os.sysconf -> long
11074 name: sysconf_confname
11075 /
11076
11077Return an integer-valued system configuration variable.
11078[clinic start generated code]*/
11079
Larry Hastings2f936352014-08-05 14:04:04 +100011080static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011081os_sysconf_impl(PyObject *module, int name)
11082/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011083{
11084 long value;
11085
11086 errno = 0;
11087 value = sysconf(name);
11088 if (value == -1 && errno != 0)
11089 posix_error();
11090 return value;
11091}
11092#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011093
11094
Fred Drakebec628d1999-12-15 18:31:10 +000011095/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011096 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011097 * the exported dictionaries that are used to publish information about the
11098 * names available on the host platform.
11099 *
11100 * Sorting the table at runtime ensures that the table is properly ordered
11101 * when used, even for platforms we're not able to test on. It also makes
11102 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011103 */
Fred Drakebec628d1999-12-15 18:31:10 +000011104
11105static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011106cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011107{
11108 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011110 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011112
11113 return strcmp(c1->name, c2->name);
11114}
11115
11116static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011117setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011118 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011119{
Fred Drakebec628d1999-12-15 18:31:10 +000011120 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011121 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011122
11123 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11124 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011125 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011127
Barry Warsaw3155db32000-04-13 15:20:40 +000011128 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 PyObject *o = PyLong_FromLong(table[i].value);
11130 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11131 Py_XDECREF(o);
11132 Py_DECREF(d);
11133 return -1;
11134 }
11135 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011136 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011137 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011138}
11139
Fred Drakebec628d1999-12-15 18:31:10 +000011140/* Return -1 on failure, 0 on success. */
11141static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011142setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011143{
11144#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011145 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011146 sizeof(posix_constants_pathconf)
11147 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011148 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011149 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011150#endif
11151#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011152 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011153 sizeof(posix_constants_confstr)
11154 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011155 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011156 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011157#endif
11158#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011159 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011160 sizeof(posix_constants_sysconf)
11161 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011162 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011163 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011164#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011165 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011166}
Fred Draked86ed291999-12-15 15:34:33 +000011167
11168
Larry Hastings2f936352014-08-05 14:04:04 +100011169/*[clinic input]
11170os.abort
11171
11172Abort the interpreter immediately.
11173
11174This function 'dumps core' or otherwise fails in the hardest way possible
11175on the hosting operating system. This function never returns.
11176[clinic start generated code]*/
11177
Larry Hastings2f936352014-08-05 14:04:04 +100011178static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011179os_abort_impl(PyObject *module)
11180/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011181{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011182 abort();
11183 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011184#ifndef __clang__
11185 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11186 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11187 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011188 Py_FatalError("abort() called from Python code didn't abort!");
11189 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011190#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011191}
Fred Drakebec628d1999-12-15 18:31:10 +000011192
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011193#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011194/* Grab ShellExecute dynamically from shell32 */
11195static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011196static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11197 LPCWSTR, INT);
11198static int
11199check_ShellExecute()
11200{
11201 HINSTANCE hShell32;
11202
11203 /* only recheck */
11204 if (-1 == has_ShellExecute) {
11205 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011206 /* Security note: this call is not vulnerable to "DLL hijacking".
11207 SHELL32 is part of "KnownDLLs" and so Windows always load
11208 the system SHELL32.DLL, even if there is another SHELL32.DLL
11209 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011210 hShell32 = LoadLibraryW(L"SHELL32");
11211 Py_END_ALLOW_THREADS
11212 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011213 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11214 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011215 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011216 } else {
11217 has_ShellExecute = 0;
11218 }
11219 }
11220 return has_ShellExecute;
11221}
11222
11223
Steve Dowercc16be82016-09-08 10:35:16 -070011224/*[clinic input]
11225os.startfile
11226 filepath: path_t
11227 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011228
Steve Dowercc16be82016-09-08 10:35:16 -070011229startfile(filepath [, operation])
11230
11231Start a file with its associated application.
11232
11233When "operation" is not specified or "open", this acts like
11234double-clicking the file in Explorer, or giving the file name as an
11235argument to the DOS "start" command: the file is opened with whatever
11236application (if any) its extension is associated.
11237When another "operation" is given, it specifies what should be done with
11238the file. A typical operation is "print".
11239
11240startfile returns as soon as the associated application is launched.
11241There is no option to wait for the application to close, and no way
11242to retrieve the application's exit status.
11243
11244The filepath is relative to the current directory. If you want to use
11245an absolute path, make sure the first character is not a slash ("/");
11246the underlying Win32 ShellExecute function doesn't work if it is.
11247[clinic start generated code]*/
11248
11249static PyObject *
11250os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
11251/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
11252{
11253 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011254
11255 if(!check_ShellExecute()) {
11256 /* If the OS doesn't have ShellExecute, return a
11257 NotImplementedError. */
11258 return PyErr_Format(PyExc_NotImplementedError,
11259 "startfile not available on this platform");
11260 }
11261
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011263 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011264 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 Py_END_ALLOW_THREADS
11266
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011268 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011269 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 }
Steve Dowercc16be82016-09-08 10:35:16 -070011271 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011272}
Larry Hastings2f936352014-08-05 14:04:04 +100011273#endif /* MS_WINDOWS */
11274
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011275
Martin v. Löwis438b5342002-12-27 10:16:42 +000011276#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011277/*[clinic input]
11278os.getloadavg
11279
11280Return average recent system load information.
11281
11282Return the number of processes in the system run queue averaged over
11283the last 1, 5, and 15 minutes as a tuple of three floats.
11284Raises OSError if the load average was unobtainable.
11285[clinic start generated code]*/
11286
Larry Hastings2f936352014-08-05 14:04:04 +100011287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011288os_getloadavg_impl(PyObject *module)
11289/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011290{
11291 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011292 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011293 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11294 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011295 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011296 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011297}
Larry Hastings2f936352014-08-05 14:04:04 +100011298#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011299
Larry Hastings2f936352014-08-05 14:04:04 +100011300
11301/*[clinic input]
11302os.device_encoding
11303 fd: int
11304
11305Return a string describing the encoding of a terminal's file descriptor.
11306
11307The file descriptor must be attached to a terminal.
11308If the device is not a terminal, return None.
11309[clinic start generated code]*/
11310
Larry Hastings2f936352014-08-05 14:04:04 +100011311static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011312os_device_encoding_impl(PyObject *module, int fd)
11313/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011314{
Brett Cannonefb00c02012-02-29 18:31:31 -050011315 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011316}
11317
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011318
Larry Hastings2f936352014-08-05 14:04:04 +100011319#ifdef HAVE_SETRESUID
11320/*[clinic input]
11321os.setresuid
11322
11323 ruid: uid_t
11324 euid: uid_t
11325 suid: uid_t
11326 /
11327
11328Set the current process's real, effective, and saved user ids.
11329[clinic start generated code]*/
11330
Larry Hastings2f936352014-08-05 14:04:04 +100011331static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011332os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11333/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011334{
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 if (setresuid(ruid, euid, suid) < 0)
11336 return posix_error();
11337 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011338}
Larry Hastings2f936352014-08-05 14:04:04 +100011339#endif /* HAVE_SETRESUID */
11340
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011341
11342#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011343/*[clinic input]
11344os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011345
Larry Hastings2f936352014-08-05 14:04:04 +100011346 rgid: gid_t
11347 egid: gid_t
11348 sgid: gid_t
11349 /
11350
11351Set the current process's real, effective, and saved group ids.
11352[clinic start generated code]*/
11353
Larry Hastings2f936352014-08-05 14:04:04 +100011354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011355os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11356/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011357{
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 if (setresgid(rgid, egid, sgid) < 0)
11359 return posix_error();
11360 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011361}
Larry Hastings2f936352014-08-05 14:04:04 +100011362#endif /* HAVE_SETRESGID */
11363
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011364
11365#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011366/*[clinic input]
11367os.getresuid
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 user ids.
11370[clinic start generated code]*/
11371
Larry Hastings2f936352014-08-05 14:04:04 +100011372static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011373os_getresuid_impl(PyObject *module)
11374/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011375{
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 if (getresuid(&ruid, &euid, &suid) < 0)
11378 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011379 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11380 _PyLong_FromUid(euid),
11381 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011382}
Larry Hastings2f936352014-08-05 14:04:04 +100011383#endif /* HAVE_GETRESUID */
11384
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011385
11386#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011387/*[clinic input]
11388os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011389
Larry Hastings2f936352014-08-05 14:04:04 +100011390Return a tuple of the current process's real, effective, and saved group ids.
11391[clinic start generated code]*/
11392
Larry Hastings2f936352014-08-05 14:04:04 +100011393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011394os_getresgid_impl(PyObject *module)
11395/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011396{
11397 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011398 if (getresgid(&rgid, &egid, &sgid) < 0)
11399 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011400 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11401 _PyLong_FromGid(egid),
11402 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011403}
Larry Hastings2f936352014-08-05 14:04:04 +100011404#endif /* HAVE_GETRESGID */
11405
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011406
Benjamin Peterson9428d532011-09-14 11:45:52 -040011407#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011408/*[clinic input]
11409os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011410
Larry Hastings2f936352014-08-05 14:04:04 +100011411 path: path_t(allow_fd=True)
11412 attribute: path_t
11413 *
11414 follow_symlinks: bool = True
11415
11416Return the value of extended attribute attribute on path.
11417
BNMetricsb9427072018-11-02 15:20:19 +000011418path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011419If follow_symlinks is False, and the last element of the path is a symbolic
11420 link, getxattr will examine the symbolic link itself instead of the file
11421 the link points to.
11422
11423[clinic start generated code]*/
11424
Larry Hastings2f936352014-08-05 14:04:04 +100011425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011426os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011427 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011428/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011429{
11430 Py_ssize_t i;
11431 PyObject *buffer = NULL;
11432
11433 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11434 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011435
Larry Hastings9cf065c2012-06-22 16:30:09 -070011436 for (i = 0; ; i++) {
11437 void *ptr;
11438 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011439 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011440 Py_ssize_t buffer_size = buffer_sizes[i];
11441 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011442 path_error(path);
11443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011444 }
11445 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11446 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011447 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011448 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011449
Larry Hastings9cf065c2012-06-22 16:30:09 -070011450 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011451 if (path->fd >= 0)
11452 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011453 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011454 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011455 else
Larry Hastings2f936352014-08-05 14:04:04 +100011456 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011457 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011458
Larry Hastings9cf065c2012-06-22 16:30:09 -070011459 if (result < 0) {
11460 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011461 if (errno == ERANGE)
11462 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011463 path_error(path);
11464 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011465 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011466
Larry Hastings9cf065c2012-06-22 16:30:09 -070011467 if (result != buffer_size) {
11468 /* Can only shrink. */
11469 _PyBytes_Resize(&buffer, result);
11470 }
11471 break;
11472 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011473
Larry Hastings9cf065c2012-06-22 16:30:09 -070011474 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011475}
11476
Larry Hastings2f936352014-08-05 14:04:04 +100011477
11478/*[clinic input]
11479os.setxattr
11480
11481 path: path_t(allow_fd=True)
11482 attribute: path_t
11483 value: Py_buffer
11484 flags: int = 0
11485 *
11486 follow_symlinks: bool = True
11487
11488Set extended attribute attribute on path to value.
11489
BNMetricsb9427072018-11-02 15:20:19 +000011490path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011491If follow_symlinks is False, and the last element of the path is a symbolic
11492 link, setxattr will modify the symbolic link itself instead of the file
11493 the link points to.
11494
11495[clinic start generated code]*/
11496
Benjamin Peterson799bd802011-08-31 22:15:17 -040011497static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011498os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011499 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011500/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011501{
Larry Hastings2f936352014-08-05 14:04:04 +100011502 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011503
Larry Hastings2f936352014-08-05 14:04:04 +100011504 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011505 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011506
Benjamin Peterson799bd802011-08-31 22:15:17 -040011507 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011508 if (path->fd > -1)
11509 result = fsetxattr(path->fd, attribute->narrow,
11510 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011511 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011512 result = setxattr(path->narrow, attribute->narrow,
11513 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011514 else
Larry Hastings2f936352014-08-05 14:04:04 +100011515 result = lsetxattr(path->narrow, attribute->narrow,
11516 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011517 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011518
Larry Hastings9cf065c2012-06-22 16:30:09 -070011519 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011520 path_error(path);
11521 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011522 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011523
Larry Hastings2f936352014-08-05 14:04:04 +100011524 Py_RETURN_NONE;
11525}
11526
11527
11528/*[clinic input]
11529os.removexattr
11530
11531 path: path_t(allow_fd=True)
11532 attribute: path_t
11533 *
11534 follow_symlinks: bool = True
11535
11536Remove extended attribute attribute on path.
11537
BNMetricsb9427072018-11-02 15:20:19 +000011538path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011539If follow_symlinks is False, and the last element of the path is a symbolic
11540 link, removexattr will modify the symbolic link itself instead of the file
11541 the link points to.
11542
11543[clinic start generated code]*/
11544
Larry Hastings2f936352014-08-05 14:04:04 +100011545static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011546os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011547 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011548/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011549{
11550 ssize_t result;
11551
11552 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11553 return NULL;
11554
11555 Py_BEGIN_ALLOW_THREADS;
11556 if (path->fd > -1)
11557 result = fremovexattr(path->fd, attribute->narrow);
11558 else if (follow_symlinks)
11559 result = removexattr(path->narrow, attribute->narrow);
11560 else
11561 result = lremovexattr(path->narrow, attribute->narrow);
11562 Py_END_ALLOW_THREADS;
11563
11564 if (result) {
11565 return path_error(path);
11566 }
11567
11568 Py_RETURN_NONE;
11569}
11570
11571
11572/*[clinic input]
11573os.listxattr
11574
11575 path: path_t(allow_fd=True, nullable=True) = None
11576 *
11577 follow_symlinks: bool = True
11578
11579Return a list of extended attributes on path.
11580
BNMetricsb9427072018-11-02 15:20:19 +000011581path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011582if path is None, listxattr will examine the current directory.
11583If follow_symlinks is False, and the last element of the path is a symbolic
11584 link, listxattr will examine the symbolic link itself instead of the file
11585 the link points to.
11586[clinic start generated code]*/
11587
Larry Hastings2f936352014-08-05 14:04:04 +100011588static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011589os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011590/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011591{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011592 Py_ssize_t i;
11593 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011594 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011595 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011596
Larry Hastings2f936352014-08-05 14:04:04 +100011597 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011598 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011599
Larry Hastings2f936352014-08-05 14:04:04 +100011600 name = path->narrow ? path->narrow : ".";
11601
Larry Hastings9cf065c2012-06-22 16:30:09 -070011602 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011603 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011604 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011605 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011606 Py_ssize_t buffer_size = buffer_sizes[i];
11607 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011608 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011609 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011610 break;
11611 }
11612 buffer = PyMem_MALLOC(buffer_size);
11613 if (!buffer) {
11614 PyErr_NoMemory();
11615 break;
11616 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011617
Larry Hastings9cf065c2012-06-22 16:30:09 -070011618 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011619 if (path->fd > -1)
11620 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011621 else if (follow_symlinks)
11622 length = listxattr(name, buffer, buffer_size);
11623 else
11624 length = llistxattr(name, buffer, buffer_size);
11625 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011626
Larry Hastings9cf065c2012-06-22 16:30:09 -070011627 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011628 if (errno == ERANGE) {
11629 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011630 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011631 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011632 }
Larry Hastings2f936352014-08-05 14:04:04 +100011633 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011634 break;
11635 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011636
Larry Hastings9cf065c2012-06-22 16:30:09 -070011637 result = PyList_New(0);
11638 if (!result) {
11639 goto exit;
11640 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011641
Larry Hastings9cf065c2012-06-22 16:30:09 -070011642 end = buffer + length;
11643 for (trace = start = buffer; trace != end; trace++) {
11644 if (!*trace) {
11645 int error;
11646 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11647 trace - start);
11648 if (!attribute) {
11649 Py_DECREF(result);
11650 result = NULL;
11651 goto exit;
11652 }
11653 error = PyList_Append(result, attribute);
11654 Py_DECREF(attribute);
11655 if (error) {
11656 Py_DECREF(result);
11657 result = NULL;
11658 goto exit;
11659 }
11660 start = trace + 1;
11661 }
11662 }
11663 break;
11664 }
11665exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011666 if (buffer)
11667 PyMem_FREE(buffer);
11668 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011669}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011670#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011671
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011672
Larry Hastings2f936352014-08-05 14:04:04 +100011673/*[clinic input]
11674os.urandom
11675
11676 size: Py_ssize_t
11677 /
11678
11679Return a bytes object containing random bytes suitable for cryptographic use.
11680[clinic start generated code]*/
11681
Larry Hastings2f936352014-08-05 14:04:04 +100011682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011683os_urandom_impl(PyObject *module, Py_ssize_t size)
11684/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011685{
11686 PyObject *bytes;
11687 int result;
11688
Georg Brandl2fb477c2012-02-21 00:33:36 +010011689 if (size < 0)
11690 return PyErr_Format(PyExc_ValueError,
11691 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011692 bytes = PyBytes_FromStringAndSize(NULL, size);
11693 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011694 return NULL;
11695
Victor Stinnere66987e2016-09-06 16:33:52 -070011696 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011697 if (result == -1) {
11698 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011699 return NULL;
11700 }
Larry Hastings2f936352014-08-05 14:04:04 +100011701 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011702}
11703
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011704/* Terminal size querying */
11705
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011706static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011707
11708PyDoc_STRVAR(TerminalSize_docstring,
11709 "A tuple of (columns, lines) for holding terminal window size");
11710
11711static PyStructSequence_Field TerminalSize_fields[] = {
11712 {"columns", "width of the terminal window in characters"},
11713 {"lines", "height of the terminal window in characters"},
11714 {NULL, NULL}
11715};
11716
11717static PyStructSequence_Desc TerminalSize_desc = {
11718 "os.terminal_size",
11719 TerminalSize_docstring,
11720 TerminalSize_fields,
11721 2,
11722};
11723
11724#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011725/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011726PyDoc_STRVAR(termsize__doc__,
11727 "Return the size of the terminal window as (columns, lines).\n" \
11728 "\n" \
11729 "The optional argument fd (default standard output) specifies\n" \
11730 "which file descriptor should be queried.\n" \
11731 "\n" \
11732 "If the file descriptor is not connected to a terminal, an OSError\n" \
11733 "is thrown.\n" \
11734 "\n" \
11735 "This function will only be defined if an implementation is\n" \
11736 "available for this system.\n" \
11737 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011738 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011739 "normally be used, os.get_terminal_size is the low-level implementation.");
11740
11741static PyObject*
11742get_terminal_size(PyObject *self, PyObject *args)
11743{
11744 int columns, lines;
11745 PyObject *termsize;
11746
11747 int fd = fileno(stdout);
11748 /* Under some conditions stdout may not be connected and
11749 * fileno(stdout) may point to an invalid file descriptor. For example
11750 * GUI apps don't have valid standard streams by default.
11751 *
11752 * If this happens, and the optional fd argument is not present,
11753 * the ioctl below will fail returning EBADF. This is what we want.
11754 */
11755
11756 if (!PyArg_ParseTuple(args, "|i", &fd))
11757 return NULL;
11758
11759#ifdef TERMSIZE_USE_IOCTL
11760 {
11761 struct winsize w;
11762 if (ioctl(fd, TIOCGWINSZ, &w))
11763 return PyErr_SetFromErrno(PyExc_OSError);
11764 columns = w.ws_col;
11765 lines = w.ws_row;
11766 }
11767#endif /* TERMSIZE_USE_IOCTL */
11768
11769#ifdef TERMSIZE_USE_CONIO
11770 {
11771 DWORD nhandle;
11772 HANDLE handle;
11773 CONSOLE_SCREEN_BUFFER_INFO csbi;
11774 switch (fd) {
11775 case 0: nhandle = STD_INPUT_HANDLE;
11776 break;
11777 case 1: nhandle = STD_OUTPUT_HANDLE;
11778 break;
11779 case 2: nhandle = STD_ERROR_HANDLE;
11780 break;
11781 default:
11782 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11783 }
11784 handle = GetStdHandle(nhandle);
11785 if (handle == NULL)
11786 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11787 if (handle == INVALID_HANDLE_VALUE)
11788 return PyErr_SetFromWindowsErr(0);
11789
11790 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11791 return PyErr_SetFromWindowsErr(0);
11792
11793 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11794 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11795 }
11796#endif /* TERMSIZE_USE_CONIO */
11797
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011798 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011799 if (termsize == NULL)
11800 return NULL;
11801 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11802 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11803 if (PyErr_Occurred()) {
11804 Py_DECREF(termsize);
11805 return NULL;
11806 }
11807 return termsize;
11808}
11809#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11810
Larry Hastings2f936352014-08-05 14:04:04 +100011811
11812/*[clinic input]
11813os.cpu_count
11814
Charles-François Natali80d62e62015-08-13 20:37:08 +010011815Return the number of CPUs in the system; return None if indeterminable.
11816
11817This number is not equivalent to the number of CPUs the current process can
11818use. The number of usable CPUs can be obtained with
11819``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011820[clinic start generated code]*/
11821
Larry Hastings2f936352014-08-05 14:04:04 +100011822static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011823os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011824/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011825{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011826 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011827#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011828 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11829 Need to fallback to Vista behavior if this call isn't present */
11830 HINSTANCE hKernel32;
11831 hKernel32 = GetModuleHandleW(L"KERNEL32");
11832
11833 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11834 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11835 "GetMaximumProcessorCount");
11836 if (_GetMaximumProcessorCount != NULL) {
11837 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11838 }
11839 else {
11840 SYSTEM_INFO sysinfo;
11841 GetSystemInfo(&sysinfo);
11842 ncpu = sysinfo.dwNumberOfProcessors;
11843 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011844#elif defined(__hpux)
11845 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11846#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11847 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011848#elif defined(__DragonFly__) || \
11849 defined(__OpenBSD__) || \
11850 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011851 defined(__NetBSD__) || \
11852 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011853 int mib[2];
11854 size_t len = sizeof(ncpu);
11855 mib[0] = CTL_HW;
11856 mib[1] = HW_NCPU;
11857 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11858 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011859#endif
11860 if (ncpu >= 1)
11861 return PyLong_FromLong(ncpu);
11862 else
11863 Py_RETURN_NONE;
11864}
11865
Victor Stinnerdaf45552013-08-28 00:53:59 +020011866
Larry Hastings2f936352014-08-05 14:04:04 +100011867/*[clinic input]
11868os.get_inheritable -> bool
11869
11870 fd: int
11871 /
11872
11873Get the close-on-exe flag of the specified file descriptor.
11874[clinic start generated code]*/
11875
Larry Hastings2f936352014-08-05 14:04:04 +100011876static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011877os_get_inheritable_impl(PyObject *module, int fd)
11878/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011879{
Steve Dower8fc89802015-04-12 00:26:27 -040011880 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011881 _Py_BEGIN_SUPPRESS_IPH
11882 return_value = _Py_get_inheritable(fd);
11883 _Py_END_SUPPRESS_IPH
11884 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011885}
11886
11887
11888/*[clinic input]
11889os.set_inheritable
11890 fd: int
11891 inheritable: int
11892 /
11893
11894Set the inheritable flag of the specified file descriptor.
11895[clinic start generated code]*/
11896
Larry Hastings2f936352014-08-05 14:04:04 +100011897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011898os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11899/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011900{
Steve Dower8fc89802015-04-12 00:26:27 -040011901 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011902
Steve Dower8fc89802015-04-12 00:26:27 -040011903 _Py_BEGIN_SUPPRESS_IPH
11904 result = _Py_set_inheritable(fd, inheritable, NULL);
11905 _Py_END_SUPPRESS_IPH
11906 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011907 return NULL;
11908 Py_RETURN_NONE;
11909}
11910
11911
11912#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011913/*[clinic input]
11914os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011915 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011916 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011917
Larry Hastings2f936352014-08-05 14:04:04 +100011918Get the close-on-exe flag of the specified file descriptor.
11919[clinic start generated code]*/
11920
Larry Hastings2f936352014-08-05 14:04:04 +100011921static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011922os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011923/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011924{
11925 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011926
11927 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11928 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011929 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011930 }
11931
Larry Hastings2f936352014-08-05 14:04:04 +100011932 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011933}
11934
Victor Stinnerdaf45552013-08-28 00:53:59 +020011935
Larry Hastings2f936352014-08-05 14:04:04 +100011936/*[clinic input]
11937os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011938 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011939 inheritable: bool
11940 /
11941
11942Set the inheritable flag of the specified handle.
11943[clinic start generated code]*/
11944
Larry Hastings2f936352014-08-05 14:04:04 +100011945static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011946os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011947 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011948/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011949{
11950 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011951 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11952 PyErr_SetFromWindowsErr(0);
11953 return NULL;
11954 }
11955 Py_RETURN_NONE;
11956}
Larry Hastings2f936352014-08-05 14:04:04 +100011957#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011958
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011959#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011960/*[clinic input]
11961os.get_blocking -> bool
11962 fd: int
11963 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011964
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011965Get the blocking mode of the file descriptor.
11966
11967Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
11968[clinic start generated code]*/
11969
11970static int
11971os_get_blocking_impl(PyObject *module, int fd)
11972/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011973{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011974 int blocking;
11975
Steve Dower8fc89802015-04-12 00:26:27 -040011976 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011977 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011978 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011979 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011980}
11981
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011982/*[clinic input]
11983os.set_blocking
11984 fd: int
11985 blocking: bool(accept={int})
11986 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011987
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011988Set the blocking mode of the specified file descriptor.
11989
11990Set the O_NONBLOCK flag if blocking is False,
11991clear the O_NONBLOCK flag otherwise.
11992[clinic start generated code]*/
11993
11994static PyObject *
11995os_set_blocking_impl(PyObject *module, int fd, int blocking)
11996/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011997{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030011998 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011999
Steve Dower8fc89802015-04-12 00:26:27 -040012000 _Py_BEGIN_SUPPRESS_IPH
12001 result = _Py_set_blocking(fd, blocking);
12002 _Py_END_SUPPRESS_IPH
12003 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012004 return NULL;
12005 Py_RETURN_NONE;
12006}
12007#endif /* !MS_WINDOWS */
12008
12009
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012010/*[clinic input]
12011class os.DirEntry "DirEntry *" "&DirEntryType"
12012[clinic start generated code]*/
12013/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012014
12015typedef struct {
12016 PyObject_HEAD
12017 PyObject *name;
12018 PyObject *path;
12019 PyObject *stat;
12020 PyObject *lstat;
12021#ifdef MS_WINDOWS
12022 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012023 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012024 int got_file_index;
12025#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012026#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012027 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012028#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012029 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012030 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012031#endif
12032} DirEntry;
12033
12034static void
12035DirEntry_dealloc(DirEntry *entry)
12036{
12037 Py_XDECREF(entry->name);
12038 Py_XDECREF(entry->path);
12039 Py_XDECREF(entry->stat);
12040 Py_XDECREF(entry->lstat);
12041 Py_TYPE(entry)->tp_free((PyObject *)entry);
12042}
12043
12044/* Forward reference */
12045static int
12046DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12047
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012048/*[clinic input]
12049os.DirEntry.is_symlink -> bool
12050
12051Return True if the entry is a symbolic link; cached per entry.
12052[clinic start generated code]*/
12053
Victor Stinner6036e442015-03-08 01:58:04 +010012054static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012055os_DirEntry_is_symlink_impl(DirEntry *self)
12056/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012057{
12058#ifdef MS_WINDOWS
12059 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012060#elif defined(HAVE_DIRENT_D_TYPE)
12061 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012062 if (self->d_type != DT_UNKNOWN)
12063 return self->d_type == DT_LNK;
12064 else
12065 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012066#else
12067 /* POSIX without d_type */
12068 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012069#endif
12070}
12071
12072static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012073DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12074{
12075 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012076 STRUCT_STAT st;
12077 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012078
12079#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012080 if (!PyUnicode_FSDecoder(self->path, &ub))
12081 return NULL;
12082 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012083#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012084 if (!PyUnicode_FSConverter(self->path, &ub))
12085 return NULL;
12086 const char *path = PyBytes_AS_STRING(ub);
12087 if (self->dir_fd != DEFAULT_DIR_FD) {
12088#ifdef HAVE_FSTATAT
12089 result = fstatat(self->dir_fd, path, &st,
12090 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12091#else
12092 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12093 return NULL;
12094#endif /* HAVE_FSTATAT */
12095 }
12096 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012097#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012098 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012099 if (follow_symlinks)
12100 result = STAT(path, &st);
12101 else
12102 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012103 }
12104 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012105
12106 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012107 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012108
12109 return _pystat_fromstructstat(&st);
12110}
12111
12112static PyObject *
12113DirEntry_get_lstat(DirEntry *self)
12114{
12115 if (!self->lstat) {
12116#ifdef MS_WINDOWS
12117 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12118#else /* POSIX */
12119 self->lstat = DirEntry_fetch_stat(self, 0);
12120#endif
12121 }
12122 Py_XINCREF(self->lstat);
12123 return self->lstat;
12124}
12125
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012126/*[clinic input]
12127os.DirEntry.stat
12128 *
12129 follow_symlinks: bool = True
12130
12131Return stat_result object for the entry; cached per entry.
12132[clinic start generated code]*/
12133
Victor Stinner6036e442015-03-08 01:58:04 +010012134static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012135os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12136/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012137{
12138 if (!follow_symlinks)
12139 return DirEntry_get_lstat(self);
12140
12141 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012142 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012143 if (result == -1)
12144 return NULL;
12145 else if (result)
12146 self->stat = DirEntry_fetch_stat(self, 1);
12147 else
12148 self->stat = DirEntry_get_lstat(self);
12149 }
12150
12151 Py_XINCREF(self->stat);
12152 return self->stat;
12153}
12154
Victor Stinner6036e442015-03-08 01:58:04 +010012155/* Set exception and return -1 on error, 0 for False, 1 for True */
12156static int
12157DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12158{
12159 PyObject *stat = NULL;
12160 PyObject *st_mode = NULL;
12161 long mode;
12162 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012163#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012164 int is_symlink;
12165 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012166#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012167#ifdef MS_WINDOWS
12168 unsigned long dir_bits;
12169#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012170 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012171
12172#ifdef MS_WINDOWS
12173 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12174 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012175#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012176 is_symlink = self->d_type == DT_LNK;
12177 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12178#endif
12179
Victor Stinner35a97c02015-03-08 02:59:09 +010012180#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012181 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012182#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012183 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012184 if (!stat) {
12185 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12186 /* If file doesn't exist (anymore), then return False
12187 (i.e., say it's not a file/directory) */
12188 PyErr_Clear();
12189 return 0;
12190 }
12191 goto error;
12192 }
12193 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12194 if (!st_mode)
12195 goto error;
12196
12197 mode = PyLong_AsLong(st_mode);
12198 if (mode == -1 && PyErr_Occurred())
12199 goto error;
12200 Py_CLEAR(st_mode);
12201 Py_CLEAR(stat);
12202 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012203#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012204 }
12205 else if (is_symlink) {
12206 assert(mode_bits != S_IFLNK);
12207 result = 0;
12208 }
12209 else {
12210 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12211#ifdef MS_WINDOWS
12212 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12213 if (mode_bits == S_IFDIR)
12214 result = dir_bits != 0;
12215 else
12216 result = dir_bits == 0;
12217#else /* POSIX */
12218 if (mode_bits == S_IFDIR)
12219 result = self->d_type == DT_DIR;
12220 else
12221 result = self->d_type == DT_REG;
12222#endif
12223 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012224#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012225
12226 return result;
12227
12228error:
12229 Py_XDECREF(st_mode);
12230 Py_XDECREF(stat);
12231 return -1;
12232}
12233
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012234/*[clinic input]
12235os.DirEntry.is_dir -> bool
12236 *
12237 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012238
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012239Return True if the entry is a directory; cached per entry.
12240[clinic start generated code]*/
12241
12242static int
12243os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12244/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12245{
12246 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012247}
12248
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012249/*[clinic input]
12250os.DirEntry.is_file -> bool
12251 *
12252 follow_symlinks: bool = True
12253
12254Return True if the entry is a file; cached per entry.
12255[clinic start generated code]*/
12256
12257static int
12258os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12259/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012260{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012261 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012262}
12263
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012264/*[clinic input]
12265os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012266
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012267Return inode of the entry; cached per entry.
12268[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012269
12270static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012271os_DirEntry_inode_impl(DirEntry *self)
12272/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012273{
12274#ifdef MS_WINDOWS
12275 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012276 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012277 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012278 STRUCT_STAT stat;
12279 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012280
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012281 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012282 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012283 path = PyUnicode_AsUnicode(unicode);
12284 result = LSTAT(path, &stat);
12285 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012286
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012287 if (result != 0)
12288 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012289
12290 self->win32_file_index = stat.st_ino;
12291 self->got_file_index = 1;
12292 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012293 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12294 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012295#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012296 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12297 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012298#endif
12299}
12300
12301static PyObject *
12302DirEntry_repr(DirEntry *self)
12303{
12304 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12305}
12306
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012307/*[clinic input]
12308os.DirEntry.__fspath__
12309
12310Returns the path for the entry.
12311[clinic start generated code]*/
12312
Brett Cannon96881cd2016-06-10 14:37:21 -070012313static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012314os_DirEntry___fspath___impl(DirEntry *self)
12315/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012316{
12317 Py_INCREF(self->path);
12318 return self->path;
12319}
12320
Victor Stinner6036e442015-03-08 01:58:04 +010012321static PyMemberDef DirEntry_members[] = {
12322 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12323 "the entry's base filename, relative to scandir() \"path\" argument"},
12324 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12325 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12326 {NULL}
12327};
12328
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012329#include "clinic/posixmodule.c.h"
12330
Victor Stinner6036e442015-03-08 01:58:04 +010012331static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012332 OS_DIRENTRY_IS_DIR_METHODDEF
12333 OS_DIRENTRY_IS_FILE_METHODDEF
12334 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12335 OS_DIRENTRY_STAT_METHODDEF
12336 OS_DIRENTRY_INODE_METHODDEF
12337 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012338 {NULL}
12339};
12340
Benjamin Peterson5646de42015-04-12 17:56:34 -040012341static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012342 PyVarObject_HEAD_INIT(NULL, 0)
12343 MODNAME ".DirEntry", /* tp_name */
12344 sizeof(DirEntry), /* tp_basicsize */
12345 0, /* tp_itemsize */
12346 /* methods */
12347 (destructor)DirEntry_dealloc, /* tp_dealloc */
12348 0, /* tp_print */
12349 0, /* tp_getattr */
12350 0, /* tp_setattr */
12351 0, /* tp_compare */
12352 (reprfunc)DirEntry_repr, /* tp_repr */
12353 0, /* tp_as_number */
12354 0, /* tp_as_sequence */
12355 0, /* tp_as_mapping */
12356 0, /* tp_hash */
12357 0, /* tp_call */
12358 0, /* tp_str */
12359 0, /* tp_getattro */
12360 0, /* tp_setattro */
12361 0, /* tp_as_buffer */
12362 Py_TPFLAGS_DEFAULT, /* tp_flags */
12363 0, /* tp_doc */
12364 0, /* tp_traverse */
12365 0, /* tp_clear */
12366 0, /* tp_richcompare */
12367 0, /* tp_weaklistoffset */
12368 0, /* tp_iter */
12369 0, /* tp_iternext */
12370 DirEntry_methods, /* tp_methods */
12371 DirEntry_members, /* tp_members */
12372};
12373
12374#ifdef MS_WINDOWS
12375
12376static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012377join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012378{
12379 Py_ssize_t path_len;
12380 Py_ssize_t size;
12381 wchar_t *result;
12382 wchar_t ch;
12383
12384 if (!path_wide) { /* Default arg: "." */
12385 path_wide = L".";
12386 path_len = 1;
12387 }
12388 else {
12389 path_len = wcslen(path_wide);
12390 }
12391
12392 /* The +1's are for the path separator and the NUL */
12393 size = path_len + 1 + wcslen(filename) + 1;
12394 result = PyMem_New(wchar_t, size);
12395 if (!result) {
12396 PyErr_NoMemory();
12397 return NULL;
12398 }
12399 wcscpy(result, path_wide);
12400 if (path_len > 0) {
12401 ch = result[path_len - 1];
12402 if (ch != SEP && ch != ALTSEP && ch != L':')
12403 result[path_len++] = SEP;
12404 wcscpy(result + path_len, filename);
12405 }
12406 return result;
12407}
12408
12409static PyObject *
12410DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12411{
12412 DirEntry *entry;
12413 BY_HANDLE_FILE_INFORMATION file_info;
12414 ULONG reparse_tag;
12415 wchar_t *joined_path;
12416
12417 entry = PyObject_New(DirEntry, &DirEntryType);
12418 if (!entry)
12419 return NULL;
12420 entry->name = NULL;
12421 entry->path = NULL;
12422 entry->stat = NULL;
12423 entry->lstat = NULL;
12424 entry->got_file_index = 0;
12425
12426 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12427 if (!entry->name)
12428 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012429 if (path->narrow) {
12430 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12431 if (!entry->name)
12432 goto error;
12433 }
Victor Stinner6036e442015-03-08 01:58:04 +010012434
12435 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12436 if (!joined_path)
12437 goto error;
12438
12439 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12440 PyMem_Free(joined_path);
12441 if (!entry->path)
12442 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012443 if (path->narrow) {
12444 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12445 if (!entry->path)
12446 goto error;
12447 }
Victor Stinner6036e442015-03-08 01:58:04 +010012448
Steve Dowercc16be82016-09-08 10:35:16 -070012449 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012450 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12451
12452 return (PyObject *)entry;
12453
12454error:
12455 Py_DECREF(entry);
12456 return NULL;
12457}
12458
12459#else /* POSIX */
12460
12461static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012462join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012463{
12464 Py_ssize_t path_len;
12465 Py_ssize_t size;
12466 char *result;
12467
12468 if (!path_narrow) { /* Default arg: "." */
12469 path_narrow = ".";
12470 path_len = 1;
12471 }
12472 else {
12473 path_len = strlen(path_narrow);
12474 }
12475
12476 if (filename_len == -1)
12477 filename_len = strlen(filename);
12478
12479 /* The +1's are for the path separator and the NUL */
12480 size = path_len + 1 + filename_len + 1;
12481 result = PyMem_New(char, size);
12482 if (!result) {
12483 PyErr_NoMemory();
12484 return NULL;
12485 }
12486 strcpy(result, path_narrow);
12487 if (path_len > 0 && result[path_len - 1] != '/')
12488 result[path_len++] = '/';
12489 strcpy(result + path_len, filename);
12490 return result;
12491}
12492
12493static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012494DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012495 ino_t d_ino
12496#ifdef HAVE_DIRENT_D_TYPE
12497 , unsigned char d_type
12498#endif
12499 )
Victor Stinner6036e442015-03-08 01:58:04 +010012500{
12501 DirEntry *entry;
12502 char *joined_path;
12503
12504 entry = PyObject_New(DirEntry, &DirEntryType);
12505 if (!entry)
12506 return NULL;
12507 entry->name = NULL;
12508 entry->path = NULL;
12509 entry->stat = NULL;
12510 entry->lstat = NULL;
12511
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012512 if (path->fd != -1) {
12513 entry->dir_fd = path->fd;
12514 joined_path = NULL;
12515 }
12516 else {
12517 entry->dir_fd = DEFAULT_DIR_FD;
12518 joined_path = join_path_filename(path->narrow, name, name_len);
12519 if (!joined_path)
12520 goto error;
12521 }
Victor Stinner6036e442015-03-08 01:58:04 +010012522
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012523 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012524 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012525 if (joined_path)
12526 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012527 }
12528 else {
12529 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012530 if (joined_path)
12531 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012532 }
12533 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012534 if (!entry->name)
12535 goto error;
12536
12537 if (path->fd != -1) {
12538 entry->path = entry->name;
12539 Py_INCREF(entry->path);
12540 }
12541 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012542 goto error;
12543
Victor Stinner35a97c02015-03-08 02:59:09 +010012544#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012545 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012546#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012547 entry->d_ino = d_ino;
12548
12549 return (PyObject *)entry;
12550
12551error:
12552 Py_XDECREF(entry);
12553 return NULL;
12554}
12555
12556#endif
12557
12558
12559typedef struct {
12560 PyObject_HEAD
12561 path_t path;
12562#ifdef MS_WINDOWS
12563 HANDLE handle;
12564 WIN32_FIND_DATAW file_data;
12565 int first_time;
12566#else /* POSIX */
12567 DIR *dirp;
12568#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012569#ifdef HAVE_FDOPENDIR
12570 int fd;
12571#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012572} ScandirIterator;
12573
12574#ifdef MS_WINDOWS
12575
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012576static int
12577ScandirIterator_is_closed(ScandirIterator *iterator)
12578{
12579 return iterator->handle == INVALID_HANDLE_VALUE;
12580}
12581
Victor Stinner6036e442015-03-08 01:58:04 +010012582static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012583ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012584{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012585 HANDLE handle = iterator->handle;
12586
12587 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012588 return;
12589
Victor Stinner6036e442015-03-08 01:58:04 +010012590 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012591 Py_BEGIN_ALLOW_THREADS
12592 FindClose(handle);
12593 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012594}
12595
12596static PyObject *
12597ScandirIterator_iternext(ScandirIterator *iterator)
12598{
12599 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12600 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012601 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012602
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012603 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012604 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012605 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012606
12607 while (1) {
12608 if (!iterator->first_time) {
12609 Py_BEGIN_ALLOW_THREADS
12610 success = FindNextFileW(iterator->handle, file_data);
12611 Py_END_ALLOW_THREADS
12612 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012613 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012614 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012615 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012616 break;
12617 }
12618 }
12619 iterator->first_time = 0;
12620
12621 /* Skip over . and .. */
12622 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012623 wcscmp(file_data->cFileName, L"..") != 0) {
12624 entry = DirEntry_from_find_data(&iterator->path, file_data);
12625 if (!entry)
12626 break;
12627 return entry;
12628 }
Victor Stinner6036e442015-03-08 01:58:04 +010012629
12630 /* Loop till we get a non-dot directory or finish iterating */
12631 }
12632
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012633 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012634 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012635 return NULL;
12636}
12637
12638#else /* POSIX */
12639
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012640static int
12641ScandirIterator_is_closed(ScandirIterator *iterator)
12642{
12643 return !iterator->dirp;
12644}
12645
Victor Stinner6036e442015-03-08 01:58:04 +010012646static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012647ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012648{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012649 DIR *dirp = iterator->dirp;
12650
12651 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012652 return;
12653
Victor Stinner6036e442015-03-08 01:58:04 +010012654 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012655 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012656#ifdef HAVE_FDOPENDIR
12657 if (iterator->path.fd != -1)
12658 rewinddir(dirp);
12659#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012660 closedir(dirp);
12661 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012662 return;
12663}
12664
12665static PyObject *
12666ScandirIterator_iternext(ScandirIterator *iterator)
12667{
12668 struct dirent *direntp;
12669 Py_ssize_t name_len;
12670 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012671 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012672
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012673 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012674 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012675 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012676
12677 while (1) {
12678 errno = 0;
12679 Py_BEGIN_ALLOW_THREADS
12680 direntp = readdir(iterator->dirp);
12681 Py_END_ALLOW_THREADS
12682
12683 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012684 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012685 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012686 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012687 break;
12688 }
12689
12690 /* Skip over . and .. */
12691 name_len = NAMLEN(direntp);
12692 is_dot = direntp->d_name[0] == '.' &&
12693 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12694 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012695 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012696 name_len, direntp->d_ino
12697#ifdef HAVE_DIRENT_D_TYPE
12698 , direntp->d_type
12699#endif
12700 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012701 if (!entry)
12702 break;
12703 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012704 }
12705
12706 /* Loop till we get a non-dot directory or finish iterating */
12707 }
12708
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012709 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012710 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012711 return NULL;
12712}
12713
12714#endif
12715
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012716static PyObject *
12717ScandirIterator_close(ScandirIterator *self, PyObject *args)
12718{
12719 ScandirIterator_closedir(self);
12720 Py_RETURN_NONE;
12721}
12722
12723static PyObject *
12724ScandirIterator_enter(PyObject *self, PyObject *args)
12725{
12726 Py_INCREF(self);
12727 return self;
12728}
12729
12730static PyObject *
12731ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12732{
12733 ScandirIterator_closedir(self);
12734 Py_RETURN_NONE;
12735}
12736
Victor Stinner6036e442015-03-08 01:58:04 +010012737static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012738ScandirIterator_finalize(ScandirIterator *iterator)
12739{
12740 PyObject *error_type, *error_value, *error_traceback;
12741
12742 /* Save the current exception, if any. */
12743 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12744
12745 if (!ScandirIterator_is_closed(iterator)) {
12746 ScandirIterator_closedir(iterator);
12747
12748 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12749 "unclosed scandir iterator %R", iterator)) {
12750 /* Spurious errors can appear at shutdown */
12751 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12752 PyErr_WriteUnraisable((PyObject *) iterator);
12753 }
12754 }
12755 }
12756
Victor Stinner7bfa4092016-03-23 00:43:54 +010012757 path_cleanup(&iterator->path);
12758
12759 /* Restore the saved exception. */
12760 PyErr_Restore(error_type, error_value, error_traceback);
12761}
12762
12763static void
Victor Stinner6036e442015-03-08 01:58:04 +010012764ScandirIterator_dealloc(ScandirIterator *iterator)
12765{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012766 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12767 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012768
Victor Stinner6036e442015-03-08 01:58:04 +010012769 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12770}
12771
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012772static PyMethodDef ScandirIterator_methods[] = {
12773 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12774 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12775 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12776 {NULL}
12777};
12778
Benjamin Peterson5646de42015-04-12 17:56:34 -040012779static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012780 PyVarObject_HEAD_INIT(NULL, 0)
12781 MODNAME ".ScandirIterator", /* tp_name */
12782 sizeof(ScandirIterator), /* tp_basicsize */
12783 0, /* tp_itemsize */
12784 /* methods */
12785 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12786 0, /* tp_print */
12787 0, /* tp_getattr */
12788 0, /* tp_setattr */
12789 0, /* tp_compare */
12790 0, /* tp_repr */
12791 0, /* tp_as_number */
12792 0, /* tp_as_sequence */
12793 0, /* tp_as_mapping */
12794 0, /* tp_hash */
12795 0, /* tp_call */
12796 0, /* tp_str */
12797 0, /* tp_getattro */
12798 0, /* tp_setattro */
12799 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012800 Py_TPFLAGS_DEFAULT
12801 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012802 0, /* tp_doc */
12803 0, /* tp_traverse */
12804 0, /* tp_clear */
12805 0, /* tp_richcompare */
12806 0, /* tp_weaklistoffset */
12807 PyObject_SelfIter, /* tp_iter */
12808 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012809 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012810 0, /* tp_members */
12811 0, /* tp_getset */
12812 0, /* tp_base */
12813 0, /* tp_dict */
12814 0, /* tp_descr_get */
12815 0, /* tp_descr_set */
12816 0, /* tp_dictoffset */
12817 0, /* tp_init */
12818 0, /* tp_alloc */
12819 0, /* tp_new */
12820 0, /* tp_free */
12821 0, /* tp_is_gc */
12822 0, /* tp_bases */
12823 0, /* tp_mro */
12824 0, /* tp_cache */
12825 0, /* tp_subclasses */
12826 0, /* tp_weaklist */
12827 0, /* tp_del */
12828 0, /* tp_version_tag */
12829 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012830};
12831
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012832/*[clinic input]
12833os.scandir
12834
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012835 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012836
12837Return an iterator of DirEntry objects for given path.
12838
BNMetricsb9427072018-11-02 15:20:19 +000012839path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012840is bytes, the names of yielded DirEntry objects will also be bytes; in
12841all other circumstances they will be str.
12842
12843If path is None, uses the path='.'.
12844[clinic start generated code]*/
12845
Victor Stinner6036e442015-03-08 01:58:04 +010012846static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012847os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012848/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012849{
12850 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012851#ifdef MS_WINDOWS
12852 wchar_t *path_strW;
12853#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012854 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012855#ifdef HAVE_FDOPENDIR
12856 int fd = -1;
12857#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012858#endif
12859
12860 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12861 if (!iterator)
12862 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012863
12864#ifdef MS_WINDOWS
12865 iterator->handle = INVALID_HANDLE_VALUE;
12866#else
12867 iterator->dirp = NULL;
12868#endif
12869
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012870 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012871 /* Move the ownership to iterator->path */
12872 path->object = NULL;
12873 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012874
12875#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012876 iterator->first_time = 1;
12877
12878 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12879 if (!path_strW)
12880 goto error;
12881
12882 Py_BEGIN_ALLOW_THREADS
12883 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12884 Py_END_ALLOW_THREADS
12885
12886 PyMem_Free(path_strW);
12887
12888 if (iterator->handle == INVALID_HANDLE_VALUE) {
12889 path_error(&iterator->path);
12890 goto error;
12891 }
12892#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012893 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012894#ifdef HAVE_FDOPENDIR
12895 if (path->fd != -1) {
12896 /* closedir() closes the FD, so we duplicate it */
12897 fd = _Py_dup(path->fd);
12898 if (fd == -1)
12899 goto error;
12900
12901 Py_BEGIN_ALLOW_THREADS
12902 iterator->dirp = fdopendir(fd);
12903 Py_END_ALLOW_THREADS
12904 }
12905 else
12906#endif
12907 {
12908 if (iterator->path.narrow)
12909 path_str = iterator->path.narrow;
12910 else
12911 path_str = ".";
12912
12913 Py_BEGIN_ALLOW_THREADS
12914 iterator->dirp = opendir(path_str);
12915 Py_END_ALLOW_THREADS
12916 }
Victor Stinner6036e442015-03-08 01:58:04 +010012917
12918 if (!iterator->dirp) {
12919 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012920#ifdef HAVE_FDOPENDIR
12921 if (fd != -1) {
12922 Py_BEGIN_ALLOW_THREADS
12923 close(fd);
12924 Py_END_ALLOW_THREADS
12925 }
12926#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012927 goto error;
12928 }
12929#endif
12930
12931 return (PyObject *)iterator;
12932
12933error:
12934 Py_DECREF(iterator);
12935 return NULL;
12936}
12937
Ethan Furman410ef8e2016-06-04 12:06:26 -070012938/*
12939 Return the file system path representation of the object.
12940
12941 If the object is str or bytes, then allow it to pass through with
12942 an incremented refcount. If the object defines __fspath__(), then
12943 return the result of that method. All other types raise a TypeError.
12944*/
12945PyObject *
12946PyOS_FSPath(PyObject *path)
12947{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012948 /* For error message reasons, this function is manually inlined in
12949 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012950 _Py_IDENTIFIER(__fspath__);
12951 PyObject *func = NULL;
12952 PyObject *path_repr = NULL;
12953
12954 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12955 Py_INCREF(path);
12956 return path;
12957 }
12958
12959 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12960 if (NULL == func) {
12961 return PyErr_Format(PyExc_TypeError,
12962 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012963 "not %.200s",
12964 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012965 }
12966
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012967 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012968 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012969 if (NULL == path_repr) {
12970 return NULL;
12971 }
12972
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012973 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12974 PyErr_Format(PyExc_TypeError,
12975 "expected %.200s.__fspath__() to return str or bytes, "
12976 "not %.200s", Py_TYPE(path)->tp_name,
12977 Py_TYPE(path_repr)->tp_name);
12978 Py_DECREF(path_repr);
12979 return NULL;
12980 }
12981
Ethan Furman410ef8e2016-06-04 12:06:26 -070012982 return path_repr;
12983}
12984
12985/*[clinic input]
12986os.fspath
12987
12988 path: object
12989
12990Return the file system path representation of the object.
12991
Brett Cannonb4f43e92016-06-09 14:32:08 -070012992If the object is str or bytes, then allow it to pass through as-is. If the
12993object defines __fspath__(), then return the result of that method. All other
12994types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012995[clinic start generated code]*/
12996
12997static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012998os_fspath_impl(PyObject *module, PyObject *path)
12999/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013000{
13001 return PyOS_FSPath(path);
13002}
Victor Stinner6036e442015-03-08 01:58:04 +010013003
Victor Stinner9b1f4742016-09-06 16:18:52 -070013004#ifdef HAVE_GETRANDOM_SYSCALL
13005/*[clinic input]
13006os.getrandom
13007
13008 size: Py_ssize_t
13009 flags: int=0
13010
13011Obtain a series of random bytes.
13012[clinic start generated code]*/
13013
13014static PyObject *
13015os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13016/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13017{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013018 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013019 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013020
13021 if (size < 0) {
13022 errno = EINVAL;
13023 return posix_error();
13024 }
13025
Victor Stinnerec2319c2016-09-20 23:00:59 +020013026 bytes = PyBytes_FromStringAndSize(NULL, size);
13027 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013028 PyErr_NoMemory();
13029 return NULL;
13030 }
13031
13032 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013033 n = syscall(SYS_getrandom,
13034 PyBytes_AS_STRING(bytes),
13035 PyBytes_GET_SIZE(bytes),
13036 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013037 if (n < 0 && errno == EINTR) {
13038 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013039 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013040 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013041
13042 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013043 continue;
13044 }
13045 break;
13046 }
13047
13048 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013049 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013050 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013051 }
13052
Victor Stinnerec2319c2016-09-20 23:00:59 +020013053 if (n != size) {
13054 _PyBytes_Resize(&bytes, n);
13055 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013056
13057 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013058
13059error:
13060 Py_DECREF(bytes);
13061 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013062}
13063#endif /* HAVE_GETRANDOM_SYSCALL */
13064
Larry Hastings31826802013-10-19 00:09:25 -070013065
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013066static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013067
13068 OS_STAT_METHODDEF
13069 OS_ACCESS_METHODDEF
13070 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013071 OS_CHDIR_METHODDEF
13072 OS_CHFLAGS_METHODDEF
13073 OS_CHMOD_METHODDEF
13074 OS_FCHMOD_METHODDEF
13075 OS_LCHMOD_METHODDEF
13076 OS_CHOWN_METHODDEF
13077 OS_FCHOWN_METHODDEF
13078 OS_LCHOWN_METHODDEF
13079 OS_LCHFLAGS_METHODDEF
13080 OS_CHROOT_METHODDEF
13081 OS_CTERMID_METHODDEF
13082 OS_GETCWD_METHODDEF
13083 OS_GETCWDB_METHODDEF
13084 OS_LINK_METHODDEF
13085 OS_LISTDIR_METHODDEF
13086 OS_LSTAT_METHODDEF
13087 OS_MKDIR_METHODDEF
13088 OS_NICE_METHODDEF
13089 OS_GETPRIORITY_METHODDEF
13090 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013091 OS_POSIX_SPAWN_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013092 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013093 OS_RENAME_METHODDEF
13094 OS_REPLACE_METHODDEF
13095 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013096 OS_SYMLINK_METHODDEF
13097 OS_SYSTEM_METHODDEF
13098 OS_UMASK_METHODDEF
13099 OS_UNAME_METHODDEF
13100 OS_UNLINK_METHODDEF
13101 OS_REMOVE_METHODDEF
13102 OS_UTIME_METHODDEF
13103 OS_TIMES_METHODDEF
13104 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013105 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013106 OS_EXECV_METHODDEF
13107 OS_EXECVE_METHODDEF
13108 OS_SPAWNV_METHODDEF
13109 OS_SPAWNVE_METHODDEF
13110 OS_FORK1_METHODDEF
13111 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013112 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013113 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13114 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13115 OS_SCHED_GETPARAM_METHODDEF
13116 OS_SCHED_GETSCHEDULER_METHODDEF
13117 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13118 OS_SCHED_SETPARAM_METHODDEF
13119 OS_SCHED_SETSCHEDULER_METHODDEF
13120 OS_SCHED_YIELD_METHODDEF
13121 OS_SCHED_SETAFFINITY_METHODDEF
13122 OS_SCHED_GETAFFINITY_METHODDEF
13123 OS_OPENPTY_METHODDEF
13124 OS_FORKPTY_METHODDEF
13125 OS_GETEGID_METHODDEF
13126 OS_GETEUID_METHODDEF
13127 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013128#ifdef HAVE_GETGROUPLIST
13129 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13130#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013131 OS_GETGROUPS_METHODDEF
13132 OS_GETPID_METHODDEF
13133 OS_GETPGRP_METHODDEF
13134 OS_GETPPID_METHODDEF
13135 OS_GETUID_METHODDEF
13136 OS_GETLOGIN_METHODDEF
13137 OS_KILL_METHODDEF
13138 OS_KILLPG_METHODDEF
13139 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013140#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013141 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013142#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013143 OS_SETUID_METHODDEF
13144 OS_SETEUID_METHODDEF
13145 OS_SETREUID_METHODDEF
13146 OS_SETGID_METHODDEF
13147 OS_SETEGID_METHODDEF
13148 OS_SETREGID_METHODDEF
13149 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013150#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013151 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013152#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013153 OS_GETPGID_METHODDEF
13154 OS_SETPGRP_METHODDEF
13155 OS_WAIT_METHODDEF
13156 OS_WAIT3_METHODDEF
13157 OS_WAIT4_METHODDEF
13158 OS_WAITID_METHODDEF
13159 OS_WAITPID_METHODDEF
13160 OS_GETSID_METHODDEF
13161 OS_SETSID_METHODDEF
13162 OS_SETPGID_METHODDEF
13163 OS_TCGETPGRP_METHODDEF
13164 OS_TCSETPGRP_METHODDEF
13165 OS_OPEN_METHODDEF
13166 OS_CLOSE_METHODDEF
13167 OS_CLOSERANGE_METHODDEF
13168 OS_DEVICE_ENCODING_METHODDEF
13169 OS_DUP_METHODDEF
13170 OS_DUP2_METHODDEF
13171 OS_LOCKF_METHODDEF
13172 OS_LSEEK_METHODDEF
13173 OS_READ_METHODDEF
13174 OS_READV_METHODDEF
13175 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013176 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013177 OS_WRITE_METHODDEF
13178 OS_WRITEV_METHODDEF
13179 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013180 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013181#ifdef HAVE_SENDFILE
13182 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
13183 posix_sendfile__doc__},
13184#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013185 OS_FSTAT_METHODDEF
13186 OS_ISATTY_METHODDEF
13187 OS_PIPE_METHODDEF
13188 OS_PIPE2_METHODDEF
13189 OS_MKFIFO_METHODDEF
13190 OS_MKNOD_METHODDEF
13191 OS_MAJOR_METHODDEF
13192 OS_MINOR_METHODDEF
13193 OS_MAKEDEV_METHODDEF
13194 OS_FTRUNCATE_METHODDEF
13195 OS_TRUNCATE_METHODDEF
13196 OS_POSIX_FALLOCATE_METHODDEF
13197 OS_POSIX_FADVISE_METHODDEF
13198 OS_PUTENV_METHODDEF
13199 OS_UNSETENV_METHODDEF
13200 OS_STRERROR_METHODDEF
13201 OS_FCHDIR_METHODDEF
13202 OS_FSYNC_METHODDEF
13203 OS_SYNC_METHODDEF
13204 OS_FDATASYNC_METHODDEF
13205 OS_WCOREDUMP_METHODDEF
13206 OS_WIFCONTINUED_METHODDEF
13207 OS_WIFSTOPPED_METHODDEF
13208 OS_WIFSIGNALED_METHODDEF
13209 OS_WIFEXITED_METHODDEF
13210 OS_WEXITSTATUS_METHODDEF
13211 OS_WTERMSIG_METHODDEF
13212 OS_WSTOPSIG_METHODDEF
13213 OS_FSTATVFS_METHODDEF
13214 OS_STATVFS_METHODDEF
13215 OS_CONFSTR_METHODDEF
13216 OS_SYSCONF_METHODDEF
13217 OS_FPATHCONF_METHODDEF
13218 OS_PATHCONF_METHODDEF
13219 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013220 OS__GETFULLPATHNAME_METHODDEF
13221 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013222 OS__GETDISKUSAGE_METHODDEF
13223 OS__GETFINALPATHNAME_METHODDEF
13224 OS__GETVOLUMEPATHNAME_METHODDEF
13225 OS_GETLOADAVG_METHODDEF
13226 OS_URANDOM_METHODDEF
13227 OS_SETRESUID_METHODDEF
13228 OS_SETRESGID_METHODDEF
13229 OS_GETRESUID_METHODDEF
13230 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013231
Larry Hastings2f936352014-08-05 14:04:04 +100013232 OS_GETXATTR_METHODDEF
13233 OS_SETXATTR_METHODDEF
13234 OS_REMOVEXATTR_METHODDEF
13235 OS_LISTXATTR_METHODDEF
13236
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013237#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13238 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13239#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013240 OS_CPU_COUNT_METHODDEF
13241 OS_GET_INHERITABLE_METHODDEF
13242 OS_SET_INHERITABLE_METHODDEF
13243 OS_GET_HANDLE_INHERITABLE_METHODDEF
13244 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013245#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013246 OS_GET_BLOCKING_METHODDEF
13247 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013248#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013249 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013250 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013251 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000013252 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013253};
13254
13255
Brian Curtin52173d42010-12-02 18:29:18 +000013256#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013257static int
Brian Curtin52173d42010-12-02 18:29:18 +000013258enable_symlink()
13259{
13260 HANDLE tok;
13261 TOKEN_PRIVILEGES tok_priv;
13262 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000013263
13264 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013265 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013266
13267 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013268 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013269
13270 tok_priv.PrivilegeCount = 1;
13271 tok_priv.Privileges[0].Luid = luid;
13272 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
13273
13274 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
13275 sizeof(TOKEN_PRIVILEGES),
13276 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000013277 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000013278
Brian Curtin3b4499c2010-12-28 14:31:47 +000013279 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
13280 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000013281}
13282#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
13283
Barry Warsaw4a342091996-12-19 23:50:02 +000013284static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013285all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013286{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013287#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013288 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013289#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013290#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013291 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013292#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013293#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013294 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013295#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013296#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013297 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013298#endif
Fred Drakec9680921999-12-13 16:37:25 +000013299#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013300 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013301#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013302#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013303 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013304#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013305#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013306 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013307#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013308#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013309 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013310#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013311#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013312 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013313#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013314#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013315 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013316#endif
13317#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013318 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013319#endif
13320#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013321 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013322#endif
13323#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013324 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013325#endif
13326#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013327 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013328#endif
13329#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013330 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013331#endif
13332#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013333 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013334#endif
13335#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013336 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013337#endif
13338#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013339 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013340#endif
13341#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013342 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013343#endif
13344#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013345 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013346#endif
13347#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013348 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013349#endif
13350#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013351 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013352#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013353#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013354 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013355#endif
13356#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013357 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013358#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013359#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013360 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013361#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013362#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013363 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013364#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013365#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013366#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013367 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013368#endif
13369#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013370 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013371#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013372#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013373#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013374 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013375#endif
13376#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013377 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013378#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013379#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013380 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013381#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013382#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013383 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013384#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013385#ifdef O_TMPFILE
13386 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13387#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013388#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013389 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013390#endif
13391#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013392 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013393#endif
13394#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013395 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013396#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013397#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013398 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013399#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013400#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013401 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013402#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013403
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013404
Jesus Cea94363612012-06-22 18:32:07 +020013405#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013406 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013407#endif
13408#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013409 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013410#endif
13411
Tim Peters5aa91602002-01-30 05:46:57 +000013412/* MS Windows */
13413#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013414 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013415 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013416#endif
13417#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013418 /* Optimize for short life (keep in memory). */
13419 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013420 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013421#endif
13422#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013423 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013424 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013425#endif
13426#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013427 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013428 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013429#endif
13430#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013431 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013432 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013433#endif
13434
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013435/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013436#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013437 /* Send a SIGIO signal whenever input or output
13438 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013439 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013440#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013441#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013442 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013443 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013444#endif
13445#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013446 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013447 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013448#endif
13449#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013450 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013451 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013452#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013453#ifdef O_NOLINKS
13454 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013455 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013456#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013457#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013458 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013459 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013460#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013461
Victor Stinner8c62be82010-05-06 00:08:46 +000013462 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013463#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013464 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013465#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013466#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013467 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013468#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013469#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013470 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013471#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013472#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013473 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013474#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013475#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013476 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013477#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013478#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013479 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013480#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013481#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013482 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013483#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013484#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013485 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013486#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013487#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013488 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013489#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013490#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013491 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013492#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013493#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013494 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013495#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013496#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013497 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013498#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013499#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013500 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013501#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013502#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013503 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013504#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013505#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013506 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013507#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013508#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013509 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013510#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013511#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013512 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013513#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013514
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013515 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013516#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013517 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013518#endif /* ST_RDONLY */
13519#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013520 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013521#endif /* ST_NOSUID */
13522
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013523 /* GNU extensions */
13524#ifdef ST_NODEV
13525 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13526#endif /* ST_NODEV */
13527#ifdef ST_NOEXEC
13528 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13529#endif /* ST_NOEXEC */
13530#ifdef ST_SYNCHRONOUS
13531 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13532#endif /* ST_SYNCHRONOUS */
13533#ifdef ST_MANDLOCK
13534 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13535#endif /* ST_MANDLOCK */
13536#ifdef ST_WRITE
13537 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13538#endif /* ST_WRITE */
13539#ifdef ST_APPEND
13540 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13541#endif /* ST_APPEND */
13542#ifdef ST_NOATIME
13543 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13544#endif /* ST_NOATIME */
13545#ifdef ST_NODIRATIME
13546 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13547#endif /* ST_NODIRATIME */
13548#ifdef ST_RELATIME
13549 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13550#endif /* ST_RELATIME */
13551
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013552 /* FreeBSD sendfile() constants */
13553#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013554 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013555#endif
13556#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013557 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013558#endif
13559#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013560 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013561#endif
13562
Ross Lagerwall7807c352011-03-17 20:20:30 +020013563 /* constants for posix_fadvise */
13564#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013565 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013566#endif
13567#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013568 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013569#endif
13570#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013571 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013572#endif
13573#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013574 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013575#endif
13576#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013577 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013578#endif
13579#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013580 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013581#endif
13582
13583 /* constants for waitid */
13584#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013585 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13586 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13587 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013588#endif
13589#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013590 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013591#endif
13592#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013593 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013594#endif
13595#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013596 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013597#endif
13598#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013599 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013600#endif
13601#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013602 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013603#endif
13604#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013605 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013606#endif
13607#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013608 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013609#endif
13610
13611 /* constants for lockf */
13612#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013613 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013614#endif
13615#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013616 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013617#endif
13618#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013619 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013620#endif
13621#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013622 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013623#endif
13624
Pablo Galindo4defba32018-01-27 16:16:37 +000013625#ifdef RWF_DSYNC
13626 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13627#endif
13628#ifdef RWF_HIPRI
13629 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13630#endif
13631#ifdef RWF_SYNC
13632 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13633#endif
13634#ifdef RWF_NOWAIT
13635 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13636#endif
13637
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013638/* constants for posix_spawn */
13639#ifdef HAVE_POSIX_SPAWN
13640 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13641 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13642 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13643#endif
13644
Guido van Rossum246bc171999-02-01 23:54:31 +000013645#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013646 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13647 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13648 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13649 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13650 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013651#endif
13652
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013653#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013654#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013655 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013656#endif
13657#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013658 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013659#endif
13660#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013661 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013662#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013663#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013664 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013665#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013666#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013667 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013668#endif
13669#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013670 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013671#endif
13672#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013673 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013674#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013675#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013676 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013677#endif
13678#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013679 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013680#endif
13681#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013682 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013683#endif
13684#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013685 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013686#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013687#endif
13688
Benjamin Peterson9428d532011-09-14 11:45:52 -040013689#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013690 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13691 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13692 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013693#endif
13694
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013695#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013696 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013697#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013698#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013699 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013700#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013701#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013702 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013703#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013704#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013705 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013706#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013707#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013708 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013709#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013710#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013711 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013712#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013713#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013714 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013715#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013716#if HAVE_DECL_RTLD_MEMBER
13717 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13718#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013719
Victor Stinner9b1f4742016-09-06 16:18:52 -070013720#ifdef HAVE_GETRANDOM_SYSCALL
13721 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13722 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13723#endif
13724
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013725#if defined(__APPLE__)
13726 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13727#endif
13728
Victor Stinner8c62be82010-05-06 00:08:46 +000013729 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013730}
13731
13732
Martin v. Löwis1a214512008-06-11 05:26:20 +000013733static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013734 PyModuleDef_HEAD_INIT,
13735 MODNAME,
13736 posix__doc__,
13737 -1,
13738 posix_methods,
13739 NULL,
13740 NULL,
13741 NULL,
13742 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013743};
13744
13745
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013746static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013747
13748#ifdef HAVE_FACCESSAT
13749 "HAVE_FACCESSAT",
13750#endif
13751
13752#ifdef HAVE_FCHDIR
13753 "HAVE_FCHDIR",
13754#endif
13755
13756#ifdef HAVE_FCHMOD
13757 "HAVE_FCHMOD",
13758#endif
13759
13760#ifdef HAVE_FCHMODAT
13761 "HAVE_FCHMODAT",
13762#endif
13763
13764#ifdef HAVE_FCHOWN
13765 "HAVE_FCHOWN",
13766#endif
13767
Larry Hastings00964ed2013-08-12 13:49:30 -040013768#ifdef HAVE_FCHOWNAT
13769 "HAVE_FCHOWNAT",
13770#endif
13771
Larry Hastings9cf065c2012-06-22 16:30:09 -070013772#ifdef HAVE_FEXECVE
13773 "HAVE_FEXECVE",
13774#endif
13775
13776#ifdef HAVE_FDOPENDIR
13777 "HAVE_FDOPENDIR",
13778#endif
13779
Georg Brandl306336b2012-06-24 12:55:33 +020013780#ifdef HAVE_FPATHCONF
13781 "HAVE_FPATHCONF",
13782#endif
13783
Larry Hastings9cf065c2012-06-22 16:30:09 -070013784#ifdef HAVE_FSTATAT
13785 "HAVE_FSTATAT",
13786#endif
13787
13788#ifdef HAVE_FSTATVFS
13789 "HAVE_FSTATVFS",
13790#endif
13791
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013792#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013793 "HAVE_FTRUNCATE",
13794#endif
13795
Larry Hastings9cf065c2012-06-22 16:30:09 -070013796#ifdef HAVE_FUTIMENS
13797 "HAVE_FUTIMENS",
13798#endif
13799
13800#ifdef HAVE_FUTIMES
13801 "HAVE_FUTIMES",
13802#endif
13803
13804#ifdef HAVE_FUTIMESAT
13805 "HAVE_FUTIMESAT",
13806#endif
13807
13808#ifdef HAVE_LINKAT
13809 "HAVE_LINKAT",
13810#endif
13811
13812#ifdef HAVE_LCHFLAGS
13813 "HAVE_LCHFLAGS",
13814#endif
13815
13816#ifdef HAVE_LCHMOD
13817 "HAVE_LCHMOD",
13818#endif
13819
13820#ifdef HAVE_LCHOWN
13821 "HAVE_LCHOWN",
13822#endif
13823
13824#ifdef HAVE_LSTAT
13825 "HAVE_LSTAT",
13826#endif
13827
13828#ifdef HAVE_LUTIMES
13829 "HAVE_LUTIMES",
13830#endif
13831
13832#ifdef HAVE_MKDIRAT
13833 "HAVE_MKDIRAT",
13834#endif
13835
13836#ifdef HAVE_MKFIFOAT
13837 "HAVE_MKFIFOAT",
13838#endif
13839
13840#ifdef HAVE_MKNODAT
13841 "HAVE_MKNODAT",
13842#endif
13843
13844#ifdef HAVE_OPENAT
13845 "HAVE_OPENAT",
13846#endif
13847
13848#ifdef HAVE_READLINKAT
13849 "HAVE_READLINKAT",
13850#endif
13851
13852#ifdef HAVE_RENAMEAT
13853 "HAVE_RENAMEAT",
13854#endif
13855
13856#ifdef HAVE_SYMLINKAT
13857 "HAVE_SYMLINKAT",
13858#endif
13859
13860#ifdef HAVE_UNLINKAT
13861 "HAVE_UNLINKAT",
13862#endif
13863
13864#ifdef HAVE_UTIMENSAT
13865 "HAVE_UTIMENSAT",
13866#endif
13867
13868#ifdef MS_WINDOWS
13869 "MS_WINDOWS",
13870#endif
13871
13872 NULL
13873};
13874
13875
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013876PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013877INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013878{
Victor Stinner8c62be82010-05-06 00:08:46 +000013879 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013880 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013881 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013882
Brian Curtin52173d42010-12-02 18:29:18 +000013883#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013884 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013885#endif
13886
Victor Stinner8c62be82010-05-06 00:08:46 +000013887 m = PyModule_Create(&posixmodule);
13888 if (m == NULL)
13889 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013890
Victor Stinner8c62be82010-05-06 00:08:46 +000013891 /* Initialize environ dictionary */
13892 v = convertenviron();
13893 Py_XINCREF(v);
13894 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13895 return NULL;
13896 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013897
Victor Stinner8c62be82010-05-06 00:08:46 +000013898 if (all_ins(m))
13899 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013900
Victor Stinner8c62be82010-05-06 00:08:46 +000013901 if (setup_confname_tables(m))
13902 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013903
Victor Stinner8c62be82010-05-06 00:08:46 +000013904 Py_INCREF(PyExc_OSError);
13905 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013906
Guido van Rossumb3d39562000-01-31 18:41:26 +000013907#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013908 if (posix_putenv_garbage == NULL)
13909 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013910#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013911
Victor Stinner8c62be82010-05-06 00:08:46 +000013912 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013913#if defined(HAVE_WAITID) && !defined(__APPLE__)
13914 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013915 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
13916 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013917 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013918 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013919#endif
13920
Christian Heimes25827622013-10-12 01:27:08 +020013921 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013922 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13923 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13924 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013925 StatResultType = PyStructSequence_NewType(&stat_result_desc);
13926 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013927 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013928 }
13929 structseq_new = StatResultType->tp_new;
13930 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013931
Christian Heimes25827622013-10-12 01:27:08 +020013932 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013933 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
13934 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013935 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013936 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013937#ifdef NEED_TICKS_PER_SECOND
13938# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013939 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013940# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013941 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013942# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013943 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013944# endif
13945#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013946
William Orr81574b82018-10-01 22:19:56 -070013947#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013948 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013949 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
13950 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013951 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013952 }
13953 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013954#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013955
13956 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013957 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
13958 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013959 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013960 }
Victor Stinner6036e442015-03-08 01:58:04 +010013961
13962 /* initialize scandir types */
13963 if (PyType_Ready(&ScandirIteratorType) < 0)
13964 return NULL;
13965 if (PyType_Ready(&DirEntryType) < 0)
13966 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013967 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013968#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013969 Py_INCREF((PyObject*) WaitidResultType);
13970 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020013971#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013972 Py_INCREF((PyObject*) StatResultType);
13973 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
13974 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000013975 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013976 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013977
13978#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013979 Py_INCREF(SchedParamType);
13980 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013981#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013982
Larry Hastings605a62d2012-06-24 04:33:36 -070013983 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013984 TimesResultType = PyStructSequence_NewType(&times_result_desc);
13985 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013986 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013987 }
13988 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070013989
13990 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013991 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
13992 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020013993 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080013994 }
13995 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070013996
Thomas Wouters477c8d52006-05-27 19:21:47 +000013997#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013998 /*
13999 * Step 2 of weak-linking support on Mac OS X.
14000 *
14001 * The code below removes functions that are not available on the
14002 * currently active platform.
14003 *
14004 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014005 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014006 * OSX 10.4.
14007 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014008#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014009 if (fstatvfs == NULL) {
14010 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14011 return NULL;
14012 }
14013 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014014#endif /* HAVE_FSTATVFS */
14015
14016#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014017 if (statvfs == NULL) {
14018 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14019 return NULL;
14020 }
14021 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014022#endif /* HAVE_STATVFS */
14023
14024# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014025 if (lchown == NULL) {
14026 if (PyObject_DelAttrString(m, "lchown") == -1) {
14027 return NULL;
14028 }
14029 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014030#endif /* HAVE_LCHOWN */
14031
14032
14033#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014034
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014035 Py_INCREF(TerminalSizeType);
14036 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014037
Larry Hastings6fe20b32012-04-19 15:07:49 -070014038 billion = PyLong_FromLong(1000000000);
14039 if (!billion)
14040 return NULL;
14041
Larry Hastings9cf065c2012-06-22 16:30:09 -070014042 /* suppress "function not used" warnings */
14043 {
14044 int ignored;
14045 fd_specified("", -1);
14046 follow_symlinks_specified("", 1);
14047 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14048 dir_fd_converter(Py_None, &ignored);
14049 dir_fd_unavailable(Py_None, &ignored);
14050 }
14051
14052 /*
14053 * provide list of locally available functions
14054 * so os.py can populate support_* lists
14055 */
14056 list = PyList_New(0);
14057 if (!list)
14058 return NULL;
14059 for (trace = have_functions; *trace; trace++) {
14060 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14061 if (!unicode)
14062 return NULL;
14063 if (PyList_Append(list, unicode))
14064 return NULL;
14065 Py_DECREF(unicode);
14066 }
14067 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014068
14069 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014070 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014071
14072 initialized = 1;
14073
Victor Stinner8c62be82010-05-06 00:08:46 +000014074 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014075}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014076
14077#ifdef __cplusplus
14078}
14079#endif