blob: b2fd45b901136b715849c7bad1b5121fef887888 [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"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020028#ifdef MS_WINDOWS
29 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
30
31 #define WIN32_LEAN_AND_MEAN
32 #include <windows.h>
33
34 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
35# include <windows.h>
36#endif
37
38#include "pycore_ceval.h" /* _PyEval_ReInitThreads() */
Victor Stinner01b63ec2019-06-19 00:48:09 +020039#include "pycore_import.h" /* _PyImport_ReInitLock() */
Victor Stinnerd5d9e812019-05-13 12:35:37 +020040#include "pycore_pystate.h" /* _PyRuntime */
Antoine Pitrou346cbd32017-05-27 17:50:54 +020041#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010042#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020043#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020044# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010045#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020046# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020047#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020049/* On android API level 21, 'AT_EACCESS' is not declared although
50 * HAVE_FACCESSAT is defined. */
51#ifdef __ANDROID__
52#undef HAVE_FACCESSAT
53#endif
54
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000055#include <stdio.h> /* needed for ctermid() */
56
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000057#ifdef __cplusplus
58extern "C" {
59#endif
60
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000061PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000062"This module provides access to operating system functionality that is\n\
63standardized by the C Standard and the POSIX standard (a thinly\n\
64disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000065corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000067
Ross Lagerwall4d076da2011-03-18 06:56:53 +020068#ifdef HAVE_SYS_UIO_H
69#include <sys/uio.h>
70#endif
71
Christian Heimes75b96182017-09-05 15:53:09 +020072#ifdef HAVE_SYS_SYSMACROS_H
73/* GNU C Library: major(), minor(), makedev() */
74#include <sys/sysmacros.h>
75#endif
76
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000078#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#endif /* HAVE_SYS_TYPES_H */
80
81#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000083#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000084
Guido van Rossum36bc6801995-06-14 22:54:23 +000085#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000086#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000087#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000088
Thomas Wouters0e3f5912006-08-11 14:57:12 +000089#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000090#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000091#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000092
Guido van Rossumb6775db1994-08-01 11:34:53 +000093#ifdef HAVE_FCNTL_H
94#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000095#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000096
Guido van Rossuma6535fd2001-10-18 19:44:10 +000097#ifdef HAVE_GRP_H
98#include <grp.h>
99#endif
100
Barry Warsaw5676bd12003-01-07 20:57:09 +0000101#ifdef HAVE_SYSEXITS_H
102#include <sysexits.h>
103#endif /* HAVE_SYSEXITS_H */
104
Anthony Baxter8a560de2004-10-13 15:30:56 +0000105#ifdef HAVE_SYS_LOADAVG_H
106#include <sys/loadavg.h>
107#endif
108
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000109#ifdef HAVE_SYS_SENDFILE_H
110#include <sys/sendfile.h>
111#endif
112
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200113#if defined(__APPLE__)
114#include <copyfile.h>
115#endif
116
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500117#ifdef HAVE_SCHED_H
118#include <sched.h>
119#endif
120
Pablo Galindoaac4d032019-05-31 19:39:47 +0100121#ifdef HAVE_COPY_FILE_RANGE
122#include <unistd.h>
123#endif
124
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500125#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500126#undef HAVE_SCHED_SETAFFINITY
127#endif
128
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200129#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400130#define USE_XATTRS
131#endif
132
133#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400134#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400135#endif
136
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000137#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
138#ifdef HAVE_SYS_SOCKET_H
139#include <sys/socket.h>
140#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000141#endif
142
Victor Stinner8b905bd2011-10-25 13:34:04 +0200143#ifdef HAVE_DLFCN_H
144#include <dlfcn.h>
145#endif
146
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200147#ifdef __hpux
148#include <sys/mpctl.h>
149#endif
150
151#if defined(__DragonFly__) || \
152 defined(__OpenBSD__) || \
153 defined(__FreeBSD__) || \
154 defined(__NetBSD__) || \
155 defined(__APPLE__)
156#include <sys/sysctl.h>
157#endif
158
Victor Stinner9b1f4742016-09-06 16:18:52 -0700159#ifdef HAVE_LINUX_RANDOM_H
160# include <linux/random.h>
161#endif
162#ifdef HAVE_GETRANDOM_SYSCALL
163# include <sys/syscall.h>
164#endif
165
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100166#if defined(MS_WINDOWS)
167# define TERMSIZE_USE_CONIO
168#elif defined(HAVE_SYS_IOCTL_H)
169# include <sys/ioctl.h>
170# if defined(HAVE_TERMIOS_H)
171# include <termios.h>
172# endif
173# if defined(TIOCGWINSZ)
174# define TERMSIZE_USE_IOCTL
175# endif
176#endif /* MS_WINDOWS */
177
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000179/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000182#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#include <process.h>
184#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000186#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000187#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000189#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700190#define HAVE_WSPAWNV 1
191#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000193#define HAVE_SYSTEM 1
194#define HAVE_CWAIT 1
195#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000196#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000197#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198/* Unix functions that the configure script doesn't check for */
pxinwrf2d7ac72019-05-21 18:46:37 +0800199#ifndef __VXWORKS__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#define HAVE_EXECV 1
201#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000202#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000203#define HAVE_FORK1 1
204#endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800205#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#define HAVE_GETEGID 1
207#define HAVE_GETEUID 1
208#define HAVE_GETGID 1
209#define HAVE_GETPPID 1
210#define HAVE_GETUID 1
211#define HAVE_KILL 1
212#define HAVE_OPENDIR 1
213#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000214#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000216#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000218#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000219
Victor Stinnera2f7c002012-02-08 03:36:25 +0100220
Larry Hastings61272b72014-01-07 12:41:53 -0800221/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000222# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800223module os
Larry Hastings61272b72014-01-07 12:41:53 -0800224[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000225/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100226
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000227#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000228
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000229#if defined(__sgi)&&_COMPILER_VERSION>=700
230/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
231 (default) */
232extern char *ctermid_r(char *);
233#endif
234
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000235#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236
pxinwrf2d7ac72019-05-21 18:46:37 +0800237#if defined(__VXWORKS__)
238#include <vxCpuLib.h>
239#include <rtpLib.h>
240#include <wait.h>
241#include <taskLib.h>
242#ifndef _P_WAIT
243#define _P_WAIT 0
244#define _P_NOWAIT 1
245#define _P_NOWAITO 1
246#endif
247#endif /* __VXWORKS__ */
248
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000249#ifdef HAVE_POSIX_SPAWN
250#include <spawn.h>
251#endif
252
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#ifdef HAVE_UTIME_H
254#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000255#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000257#ifdef HAVE_SYS_UTIME_H
258#include <sys/utime.h>
259#define HAVE_UTIME_H /* pretend we do for the rest of this file */
260#endif /* HAVE_SYS_UTIME_H */
261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_SYS_TIMES_H
263#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
266#ifdef HAVE_SYS_PARAM_H
267#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000268#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
270#ifdef HAVE_SYS_UTSNAME_H
271#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000272#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#define NAMLEN(dirent) strlen((dirent)->d_name)
277#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000278#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#include <direct.h>
280#define NAMLEN(dirent) strlen((dirent)->d_name)
281#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000284#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000287#endif
288#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000290#endif
291#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000292#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000293#endif
294#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000296#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000299#endif
300#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000302#endif
303#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000305#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000307#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000308#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100309#ifndef IO_REPARSE_TAG_MOUNT_POINT
310#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
311#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000313#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000315#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000316#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000317#define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000318#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000319
Tim Petersbc2e10e2002-03-03 23:17:02 +0000320#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000321#if defined(PATH_MAX) && PATH_MAX > 1024
322#define MAXPATHLEN PATH_MAX
323#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000326#endif /* MAXPATHLEN */
327
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000328#ifdef UNION_WAIT
329/* Emulate some macros on systems that have a union instead of macros */
330
331#ifndef WIFEXITED
332#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
333#endif
334
335#ifndef WEXITSTATUS
336#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
337#endif
338
339#ifndef WTERMSIG
340#define WTERMSIG(u_wait) ((u_wait).w_termsig)
341#endif
342
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343#define WAIT_TYPE union wait
344#define WAIT_STATUS_INT(s) (s.w_status)
345
346#else /* !UNION_WAIT */
347#define WAIT_TYPE int
348#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000349#endif /* UNION_WAIT */
350
Greg Wardb48bc172000-03-01 21:51:56 +0000351/* Don't use the "_r" form if we don't need it (also, won't have a
352 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200353#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000354#define USE_CTERMID_R
355#endif
356
Fred Drake699f3522000-06-29 21:12:41 +0000357/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000358#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000359#undef FSTAT
360#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200361#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700363# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200364# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800365# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000366#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700368# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define FSTAT fstat
370# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000371#endif
372
Tim Peters11b23062003-04-23 02:39:17 +0000373#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000374#include <sys/mkdev.h>
375#else
376#if defined(MAJOR_IN_SYSMACROS)
377#include <sys/sysmacros.h>
378#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000379#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
380#include <sys/mkdev.h>
381#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000382#endif
Fred Drake699f3522000-06-29 21:12:41 +0000383
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200384#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100385#define INITFUNC PyInit_nt
386#define MODNAME "nt"
387#else
388#define INITFUNC PyInit_posix
389#define MODNAME "posix"
390#endif
391
jcea6c51d512018-01-28 14:00:08 +0100392#if defined(__sun)
393/* Something to implement in autoconf, not present in autoconf 2.69 */
394#define HAVE_STRUCT_STAT_ST_FSTYPE 1
395#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200396
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600397/* memfd_create is either defined in sys/mman.h or sys/memfd.h
398 * linux/memfd.h defines additional flags
399 */
400#ifdef HAVE_SYS_MMAN_H
401#include <sys/mman.h>
402#endif
403#ifdef HAVE_SYS_MEMFD_H
404#include <sys/memfd.h>
405#endif
406#ifdef HAVE_LINUX_MEMFD_H
407#include <linux/memfd.h>
408#endif
409
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800410#ifdef _Py_MEMORY_SANITIZER
411# include <sanitizer/msan_interface.h>
412#endif
413
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200414#ifdef HAVE_FORK
415static void
416run_at_forkers(PyObject *lst, int reverse)
417{
418 Py_ssize_t i;
419 PyObject *cpy;
420
421 if (lst != NULL) {
422 assert(PyList_CheckExact(lst));
423
424 /* Use a list copy in case register_at_fork() is called from
425 * one of the callbacks.
426 */
427 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
428 if (cpy == NULL)
429 PyErr_WriteUnraisable(lst);
430 else {
431 if (reverse)
432 PyList_Reverse(cpy);
433 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
434 PyObject *func, *res;
435 func = PyList_GET_ITEM(cpy, i);
436 res = PyObject_CallObject(func, NULL);
437 if (res == NULL)
438 PyErr_WriteUnraisable(func);
439 else
440 Py_DECREF(res);
441 }
442 Py_DECREF(cpy);
443 }
444 }
445}
446
447void
448PyOS_BeforeFork(void)
449{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200450 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200451
452 _PyImport_AcquireLock();
453}
454
455void
456PyOS_AfterFork_Parent(void)
457{
458 if (_PyImport_ReleaseLock() <= 0)
459 Py_FatalError("failed releasing import lock after fork");
460
Victor Stinnercaba55b2018-08-03 15:33:52 +0200461 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200462}
463
464void
465PyOS_AfterFork_Child(void)
466{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200467 _PyRuntimeState *runtime = &_PyRuntime;
468 _PyGILState_Reinit(runtime);
Victor Stinnerd5d9e812019-05-13 12:35:37 +0200469 _PyEval_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200470 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200471 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200472 _PyRuntimeState_ReInitThreads(runtime);
Victor Stinnerb49858b2019-05-24 15:20:23 +0200473 _PyInterpreterState_DeleteExceptMain(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200474
Victor Stinnercaba55b2018-08-03 15:33:52 +0200475 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200476}
477
478static int
479register_at_forker(PyObject **lst, PyObject *func)
480{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700481 if (func == NULL) /* nothing to register? do nothing. */
482 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200483 if (*lst == NULL) {
484 *lst = PyList_New(0);
485 if (*lst == NULL)
486 return -1;
487 }
488 return PyList_Append(*lst, func);
489}
490#endif
491
492/* Legacy wrapper */
493void
494PyOS_AfterFork(void)
495{
496#ifdef HAVE_FORK
497 PyOS_AfterFork_Child();
498#endif
499}
500
501
Victor Stinner6036e442015-03-08 01:58:04 +0100502#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200503/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700504void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
505void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200506 ULONG, struct _Py_stat_struct *);
507#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700508
509#ifdef MS_WINDOWS
510static int
511win32_warn_bytes_api()
512{
513 return PyErr_WarnEx(PyExc_DeprecationWarning,
514 "The Windows bytes API has been deprecated, "
515 "use Unicode filenames instead",
516 1);
517}
518#endif
519
520
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200521#ifndef MS_WINDOWS
522PyObject *
523_PyLong_FromUid(uid_t uid)
524{
525 if (uid == (uid_t)-1)
526 return PyLong_FromLong(-1);
527 return PyLong_FromUnsignedLong(uid);
528}
529
530PyObject *
531_PyLong_FromGid(gid_t gid)
532{
533 if (gid == (gid_t)-1)
534 return PyLong_FromLong(-1);
535 return PyLong_FromUnsignedLong(gid);
536}
537
538int
539_Py_Uid_Converter(PyObject *obj, void *p)
540{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700541 uid_t uid;
542 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200543 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200544 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700545 unsigned long uresult;
546
547 index = PyNumber_Index(obj);
548 if (index == NULL) {
549 PyErr_Format(PyExc_TypeError,
550 "uid should be integer, not %.200s",
551 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200552 return 0;
553 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700554
555 /*
556 * Handling uid_t is complicated for two reasons:
557 * * Although uid_t is (always?) unsigned, it still
558 * accepts -1.
559 * * We don't know its size in advance--it may be
560 * bigger than an int, or it may be smaller than
561 * a long.
562 *
563 * So a bit of defensive programming is in order.
564 * Start with interpreting the value passed
565 * in as a signed long and see if it works.
566 */
567
568 result = PyLong_AsLongAndOverflow(index, &overflow);
569
570 if (!overflow) {
571 uid = (uid_t)result;
572
573 if (result == -1) {
574 if (PyErr_Occurred())
575 goto fail;
576 /* It's a legitimate -1, we're done. */
577 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200578 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700579
580 /* Any other negative number is disallowed. */
581 if (result < 0)
582 goto underflow;
583
584 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200585 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700586 (long)uid != result)
587 goto underflow;
588 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200589 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700590
591 if (overflow < 0)
592 goto underflow;
593
594 /*
595 * Okay, the value overflowed a signed long. If it
596 * fits in an *unsigned* long, it may still be okay,
597 * as uid_t may be unsigned long on this platform.
598 */
599 uresult = PyLong_AsUnsignedLong(index);
600 if (PyErr_Occurred()) {
601 if (PyErr_ExceptionMatches(PyExc_OverflowError))
602 goto overflow;
603 goto fail;
604 }
605
606 uid = (uid_t)uresult;
607
608 /*
609 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
610 * but this value would get interpreted as (uid_t)-1 by chown
611 * and its siblings. That's not what the user meant! So we
612 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100613 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614 */
615 if (uid == (uid_t)-1)
616 goto overflow;
617
618 /* Ensure the value wasn't truncated. */
619 if (sizeof(uid_t) < sizeof(long) &&
620 (unsigned long)uid != uresult)
621 goto overflow;
622 /* fallthrough */
623
624success:
625 Py_DECREF(index);
626 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200627 return 1;
628
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700629underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700631 "uid is less than minimum");
632 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200633
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200635 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700636 "uid is greater than maximum");
637 /* fallthrough */
638
639fail:
640 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 return 0;
642}
643
644int
645_Py_Gid_Converter(PyObject *obj, void *p)
646{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647 gid_t gid;
648 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200649 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200650 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700651 unsigned long uresult;
652
653 index = PyNumber_Index(obj);
654 if (index == NULL) {
655 PyErr_Format(PyExc_TypeError,
656 "gid should be integer, not %.200s",
657 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200658 return 0;
659 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700660
661 /*
662 * Handling gid_t is complicated for two reasons:
663 * * Although gid_t is (always?) unsigned, it still
664 * accepts -1.
665 * * We don't know its size in advance--it may be
666 * bigger than an int, or it may be smaller than
667 * a long.
668 *
669 * So a bit of defensive programming is in order.
670 * Start with interpreting the value passed
671 * in as a signed long and see if it works.
672 */
673
674 result = PyLong_AsLongAndOverflow(index, &overflow);
675
676 if (!overflow) {
677 gid = (gid_t)result;
678
679 if (result == -1) {
680 if (PyErr_Occurred())
681 goto fail;
682 /* It's a legitimate -1, we're done. */
683 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200684 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700685
686 /* Any other negative number is disallowed. */
687 if (result < 0) {
688 goto underflow;
689 }
690
691 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200692 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700693 (long)gid != result)
694 goto underflow;
695 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200696 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697
698 if (overflow < 0)
699 goto underflow;
700
701 /*
702 * Okay, the value overflowed a signed long. If it
703 * fits in an *unsigned* long, it may still be okay,
704 * as gid_t may be unsigned long on this platform.
705 */
706 uresult = PyLong_AsUnsignedLong(index);
707 if (PyErr_Occurred()) {
708 if (PyErr_ExceptionMatches(PyExc_OverflowError))
709 goto overflow;
710 goto fail;
711 }
712
713 gid = (gid_t)uresult;
714
715 /*
716 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
717 * but this value would get interpreted as (gid_t)-1 by chown
718 * and its siblings. That's not what the user meant! So we
719 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100720 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700721 */
722 if (gid == (gid_t)-1)
723 goto overflow;
724
725 /* Ensure the value wasn't truncated. */
726 if (sizeof(gid_t) < sizeof(long) &&
727 (unsigned long)gid != uresult)
728 goto overflow;
729 /* fallthrough */
730
731success:
732 Py_DECREF(index);
733 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200734 return 1;
735
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700736underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200737 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700738 "gid is less than minimum");
739 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200740
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700741overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200742 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700743 "gid is greater than maximum");
744 /* fallthrough */
745
746fail:
747 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200748 return 0;
749}
750#endif /* MS_WINDOWS */
751
752
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700753#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800754
755
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200756#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
757static int
758_Py_Dev_Converter(PyObject *obj, void *p)
759{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200760 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200761 if (PyErr_Occurred())
762 return 0;
763 return 1;
764}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800765#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200766
767
Larry Hastings9cf065c2012-06-22 16:30:09 -0700768#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400769/*
770 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
771 * without the int cast, the value gets interpreted as uint (4291925331),
772 * which doesn't play nicely with all the initializer lines in this file that
773 * look like this:
774 * int dir_fd = DEFAULT_DIR_FD;
775 */
776#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700777#else
778#define DEFAULT_DIR_FD (-100)
779#endif
780
781static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300782_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200783{
784 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785 long long_value;
786
787 PyObject *index = PyNumber_Index(o);
788 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 return 0;
790 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700791
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300792 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793 long_value = PyLong_AsLongAndOverflow(index, &overflow);
794 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300795 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200796 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700797 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700798 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700799 return 0;
800 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200801 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700802 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700803 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700804 return 0;
805 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700806
Larry Hastings9cf065c2012-06-22 16:30:09 -0700807 *p = (int)long_value;
808 return 1;
809}
810
811static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200812dir_fd_converter(PyObject *o, void *p)
813{
814 if (o == Py_None) {
815 *(int *)p = DEFAULT_DIR_FD;
816 return 1;
817 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300818 else if (PyIndex_Check(o)) {
819 return _fd_converter(o, (int *)p);
820 }
821 else {
822 PyErr_Format(PyExc_TypeError,
823 "argument should be integer or None, not %.200s",
824 Py_TYPE(o)->tp_name);
825 return 0;
826 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700827}
828
829
Larry Hastings9cf065c2012-06-22 16:30:09 -0700830/*
831 * A PyArg_ParseTuple "converter" function
832 * that handles filesystem paths in the manner
833 * preferred by the os module.
834 *
835 * path_converter accepts (Unicode) strings and their
836 * subclasses, and bytes and their subclasses. What
837 * it does with the argument depends on the platform:
838 *
839 * * On Windows, if we get a (Unicode) string we
840 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700841 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700842 *
843 * * On all other platforms, strings are encoded
844 * to bytes using PyUnicode_FSConverter, then we
845 * extract the char * from the bytes object and
846 * return that.
847 *
848 * path_converter also optionally accepts signed
849 * integers (representing open file descriptors) instead
850 * of path strings.
851 *
852 * Input fields:
853 * path.nullable
854 * If nonzero, the path is permitted to be None.
855 * path.allow_fd
856 * If nonzero, the path is permitted to be a file handle
857 * (a signed int) instead of a string.
858 * path.function_name
859 * If non-NULL, path_converter will use that as the name
860 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700861 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700862 * path.argument_name
863 * If non-NULL, path_converter will use that as the name
864 * of the parameter in error messages.
865 * (If path.argument_name is NULL it uses "path".)
866 *
867 * Output fields:
868 * path.wide
869 * Points to the path if it was expressed as Unicode
870 * and was not encoded. (Only used on Windows.)
871 * path.narrow
872 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700873 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000874 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700875 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876 * path.fd
877 * Contains a file descriptor if path.accept_fd was true
878 * and the caller provided a signed integer instead of any
879 * sort of string.
880 *
881 * WARNING: if your "path" parameter is optional, and is
882 * unspecified, path_converter will never get called.
883 * So if you set allow_fd, you *MUST* initialize path.fd = -1
884 * yourself!
885 * path.length
886 * The length of the path in characters, if specified as
887 * a string.
888 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800889 * The original object passed in (if get a PathLike object,
890 * the result of PyOS_FSPath() is treated as the original object).
891 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700892 * path.cleanup
893 * For internal use only. May point to a temporary object.
894 * (Pay no attention to the man behind the curtain.)
895 *
896 * At most one of path.wide or path.narrow will be non-NULL.
897 * If path was None and path.nullable was set,
898 * or if path was an integer and path.allow_fd was set,
899 * both path.wide and path.narrow will be NULL
900 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200901 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700902 * path_converter takes care to not write to the path_t
903 * unless it's successful. However it must reset the
904 * "cleanup" field each time it's called.
905 *
906 * Use as follows:
907 * path_t path;
908 * memset(&path, 0, sizeof(path));
909 * PyArg_ParseTuple(args, "O&", path_converter, &path);
910 * // ... use values from path ...
911 * path_cleanup(&path);
912 *
913 * (Note that if PyArg_Parse fails you don't need to call
914 * path_cleanup(). However it is safe to do so.)
915 */
916typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100917 const char *function_name;
918 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700919 int nullable;
920 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300921 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700922#ifdef MS_WINDOWS
923 BOOL narrow;
924#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300925 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700926#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700927 int fd;
928 Py_ssize_t length;
929 PyObject *object;
930 PyObject *cleanup;
931} path_t;
932
Steve Dowercc16be82016-09-08 10:35:16 -0700933#ifdef MS_WINDOWS
934#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
935 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
936#else
Larry Hastings2f936352014-08-05 14:04:04 +1000937#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
938 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700939#endif
Larry Hastings31826802013-10-19 00:09:25 -0700940
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800942path_cleanup(path_t *path)
943{
944 Py_CLEAR(path->object);
945 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946}
947
948static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300949path_converter(PyObject *o, void *p)
950{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700951 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800952 PyObject *bytes = NULL;
953 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700954 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300955 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700956#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800957 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700958 const wchar_t *wide;
959#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960
961#define FORMAT_EXCEPTION(exc, fmt) \
962 PyErr_Format(exc, "%s%s" fmt, \
963 path->function_name ? path->function_name : "", \
964 path->function_name ? ": " : "", \
965 path->argument_name ? path->argument_name : "path")
966
967 /* Py_CLEANUP_SUPPORTED support */
968 if (o == NULL) {
969 path_cleanup(path);
970 return 1;
971 }
972
Brett Cannon3f9183b2016-08-26 14:44:48 -0700973 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800974 path->object = path->cleanup = NULL;
975 /* path->object owns a reference to the original object */
976 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700977
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300978 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700979 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700980#ifdef MS_WINDOWS
981 path->narrow = FALSE;
982#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700983 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700984#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700985 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800986 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700987 }
988
Brett Cannon3f9183b2016-08-26 14:44:48 -0700989 /* Only call this here so that we don't treat the return value of
990 os.fspath() as an fd or buffer. */
991 is_index = path->allow_fd && PyIndex_Check(o);
992 is_buffer = PyObject_CheckBuffer(o);
993 is_bytes = PyBytes_Check(o);
994 is_unicode = PyUnicode_Check(o);
995
996 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
997 /* Inline PyOS_FSPath() for better error messages. */
998 _Py_IDENTIFIER(__fspath__);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000999 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001000
1001 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1002 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001003 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001004 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001005 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001006 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001007 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001008 goto error_exit;
1009 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001010 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001011 is_unicode = 1;
1012 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001013 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001014 is_bytes = 1;
1015 }
1016 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001017 PyErr_Format(PyExc_TypeError,
1018 "expected %.200s.__fspath__() to return str or bytes, "
1019 "not %.200s", Py_TYPE(o)->tp_name,
1020 Py_TYPE(res)->tp_name);
1021 Py_DECREF(res);
1022 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001023 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001024
1025 /* still owns a reference to the original object */
1026 Py_DECREF(o);
1027 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001028 }
1029
1030 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001031#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001032 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001033 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001034 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 }
Victor Stinner59799a82013-11-13 14:17:30 +01001036 if (length > 32767) {
1037 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001038 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001039 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001040 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001041 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001042 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001043 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001044
1045 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001046 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001047 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001048 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001049#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001050 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001052 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001053#endif
1054 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001055 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001056 bytes = o;
1057 Py_INCREF(bytes);
1058 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001059 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001060 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001061 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001062 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1063 "%s%s%s should be %s, not %.200s",
1064 path->function_name ? path->function_name : "",
1065 path->function_name ? ": " : "",
1066 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001067 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1068 "integer or None" :
1069 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1070 path->nullable ? "string, bytes, os.PathLike or None" :
1071 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001072 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001073 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001074 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001075 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001077 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001078 }
1079 }
Steve Dowercc16be82016-09-08 10:35:16 -07001080 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001081 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001082 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001083 }
1084 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001085#ifdef MS_WINDOWS
1086 path->narrow = FALSE;
1087#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001088 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001089#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001090 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001091 }
1092 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001093 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001094 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1095 path->function_name ? path->function_name : "",
1096 path->function_name ? ": " : "",
1097 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001098 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1099 "integer or None" :
1100 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1101 path->nullable ? "string, bytes, os.PathLike or None" :
1102 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001103 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001104 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001105 }
1106
Larry Hastings9cf065c2012-06-22 16:30:09 -07001107 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001108 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001109 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001110 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001111 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001112 }
1113
Steve Dowercc16be82016-09-08 10:35:16 -07001114#ifdef MS_WINDOWS
1115 wo = PyUnicode_DecodeFSDefaultAndSize(
1116 narrow,
1117 length
1118 );
1119 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001120 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001121 }
1122
Xiang Zhang04316c42017-01-08 23:26:57 +08001123 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001124 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001125 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001126 }
1127 if (length > 32767) {
1128 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001129 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001130 }
1131 if (wcslen(wide) != length) {
1132 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001133 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001134 }
1135 path->wide = wide;
1136 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001137 path->cleanup = wo;
1138 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001139#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001140 path->wide = NULL;
1141 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001142 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001143 /* Still a reference owned by path->object, don't have to
1144 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001145 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001146 }
1147 else {
1148 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001149 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001150#endif
1151 path->fd = -1;
1152
1153 success_exit:
1154 path->length = length;
1155 path->object = o;
1156 return Py_CLEANUP_SUPPORTED;
1157
1158 error_exit:
1159 Py_XDECREF(o);
1160 Py_XDECREF(bytes);
1161#ifdef MS_WINDOWS
1162 Py_XDECREF(wo);
1163#endif
1164 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165}
1166
1167static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001168argument_unavailable_error(const char *function_name, const char *argument_name)
1169{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 PyErr_Format(PyExc_NotImplementedError,
1171 "%s%s%s unavailable on this platform",
1172 (function_name != NULL) ? function_name : "",
1173 (function_name != NULL) ? ": ": "",
1174 argument_name);
1175}
1176
1177static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001178dir_fd_unavailable(PyObject *o, void *p)
1179{
1180 int dir_fd;
1181 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001182 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001183 if (dir_fd != DEFAULT_DIR_FD) {
1184 argument_unavailable_error(NULL, "dir_fd");
1185 return 0;
1186 }
1187 *(int *)p = dir_fd;
1188 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001189}
1190
1191static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001192fd_specified(const char *function_name, int fd)
1193{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001194 if (fd == -1)
1195 return 0;
1196
1197 argument_unavailable_error(function_name, "fd");
1198 return 1;
1199}
1200
1201static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001202follow_symlinks_specified(const char *function_name, int follow_symlinks)
1203{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001204 if (follow_symlinks)
1205 return 0;
1206
1207 argument_unavailable_error(function_name, "follow_symlinks");
1208 return 1;
1209}
1210
1211static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001212path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1213{
Steve Dowercc16be82016-09-08 10:35:16 -07001214 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1215#ifndef MS_WINDOWS
1216 && !path->narrow
1217#endif
1218 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 PyErr_Format(PyExc_ValueError,
1220 "%s: can't specify dir_fd without matching path",
1221 function_name);
1222 return 1;
1223 }
1224 return 0;
1225}
1226
1227static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001228dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1229{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001230 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1231 PyErr_Format(PyExc_ValueError,
1232 "%s: can't specify both dir_fd and fd",
1233 function_name);
1234 return 1;
1235 }
1236 return 0;
1237}
1238
1239static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001240fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1241 int follow_symlinks)
1242{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001243 if ((fd > 0) && (!follow_symlinks)) {
1244 PyErr_Format(PyExc_ValueError,
1245 "%s: cannot use fd and follow_symlinks together",
1246 function_name);
1247 return 1;
1248 }
1249 return 0;
1250}
1251
1252static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001253dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1254 int follow_symlinks)
1255{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001256 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1257 PyErr_Format(PyExc_ValueError,
1258 "%s: cannot use dir_fd and follow_symlinks together",
1259 function_name);
1260 return 1;
1261 }
1262 return 0;
1263}
1264
Larry Hastings2f936352014-08-05 14:04:04 +10001265#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001266 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001267#else
Larry Hastings2f936352014-08-05 14:04:04 +10001268 typedef off_t Py_off_t;
1269#endif
1270
1271static int
1272Py_off_t_converter(PyObject *arg, void *addr)
1273{
1274#ifdef HAVE_LARGEFILE_SUPPORT
1275 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1276#else
1277 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001278#endif
1279 if (PyErr_Occurred())
1280 return 0;
1281 return 1;
1282}
Larry Hastings2f936352014-08-05 14:04:04 +10001283
1284static PyObject *
1285PyLong_FromPy_off_t(Py_off_t offset)
1286{
1287#ifdef HAVE_LARGEFILE_SUPPORT
1288 return PyLong_FromLongLong(offset);
1289#else
1290 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001291#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001292}
1293
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001294#ifdef HAVE_SIGSET_T
1295/* Convert an iterable of integers to a sigset.
1296 Return 1 on success, return 0 and raise an exception on error. */
1297int
1298_Py_Sigset_Converter(PyObject *obj, void *addr)
1299{
1300 sigset_t *mask = (sigset_t *)addr;
1301 PyObject *iterator, *item;
1302 long signum;
1303 int overflow;
1304
Rémi Lapeyref0900192019-05-04 01:30:53 +02001305 // The extra parens suppress the unreachable-code warning with clang on MacOS
1306 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001307 /* Probably only if mask == NULL. */
1308 PyErr_SetFromErrno(PyExc_OSError);
1309 return 0;
1310 }
1311
1312 iterator = PyObject_GetIter(obj);
1313 if (iterator == NULL) {
1314 return 0;
1315 }
1316
1317 while ((item = PyIter_Next(iterator)) != NULL) {
1318 signum = PyLong_AsLongAndOverflow(item, &overflow);
1319 Py_DECREF(item);
1320 if (signum <= 0 || signum >= NSIG) {
1321 if (overflow || signum != -1 || !PyErr_Occurred()) {
1322 PyErr_Format(PyExc_ValueError,
1323 "signal number %ld out of range", signum);
1324 }
1325 goto error;
1326 }
1327 if (sigaddset(mask, (int)signum)) {
1328 if (errno != EINVAL) {
1329 /* Probably impossible */
1330 PyErr_SetFromErrno(PyExc_OSError);
1331 goto error;
1332 }
1333 /* For backwards compatibility, allow idioms such as
1334 * `range(1, NSIG)` but warn about invalid signal numbers
1335 */
1336 const char msg[] =
1337 "invalid signal number %ld, please use valid_signals()";
1338 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1339 goto error;
1340 }
1341 }
1342 }
1343 if (!PyErr_Occurred()) {
1344 Py_DECREF(iterator);
1345 return 1;
1346 }
1347
1348error:
1349 Py_DECREF(iterator);
1350 return 0;
1351}
1352#endif /* HAVE_SIGSET_T */
1353
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001354#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001355
1356static int
Brian Curtind25aef52011-06-13 15:16:04 -05001357win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001358{
Martin Panter70214ad2016-08-04 02:38:59 +00001359 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1360 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001361 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001362
1363 if (0 == DeviceIoControl(
1364 reparse_point_handle,
1365 FSCTL_GET_REPARSE_POINT,
1366 NULL, 0, /* in buffer */
1367 target_buffer, sizeof(target_buffer),
1368 &n_bytes_returned,
1369 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001370 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001371
1372 if (reparse_tag)
1373 *reparse_tag = rdb->ReparseTag;
1374
Brian Curtind25aef52011-06-13 15:16:04 -05001375 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001376}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001377
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001378#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001379
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001380/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001381#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001382/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001383** environ directly, we must obtain it with _NSGetEnviron(). See also
1384** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001385*/
1386#include <crt_externs.h>
1387static char **environ;
pxinwrf2d7ac72019-05-21 18:46:37 +08001388#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001389extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001390#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001391
Barry Warsaw53699e91996-12-10 23:23:01 +00001392static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001393convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001394{
Victor Stinner8c62be82010-05-06 00:08:46 +00001395 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001396#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001397 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001398#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001399 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001400#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001401
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 d = PyDict_New();
1403 if (d == NULL)
1404 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001405#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 if (environ == NULL)
1407 environ = *_NSGetEnviron();
1408#endif
1409#ifdef MS_WINDOWS
1410 /* _wenviron must be initialized in this way if the program is started
1411 through main() instead of wmain(). */
1412 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001413 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001414#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001415 e = environ;
1416#endif
1417 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001419 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 PyObject *k;
1421 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001422#ifdef MS_WINDOWS
1423 const wchar_t *p = wcschr(*e, L'=');
1424#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001425 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001426#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 if (p == NULL)
1428 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001429#ifdef MS_WINDOWS
1430 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1431#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001432 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001433#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001434 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001435 Py_DECREF(d);
1436 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001438#ifdef MS_WINDOWS
1439 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1440#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001441 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001442#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001445 Py_DECREF(d);
1446 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001448 if (PyDict_GetItemWithError(d, k) == NULL) {
1449 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1450 Py_DECREF(v);
1451 Py_DECREF(k);
1452 Py_DECREF(d);
1453 return NULL;
1454 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 }
1456 Py_DECREF(k);
1457 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001458 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001460}
1461
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001462/* Set a POSIX-specific error from errno, and return NULL */
1463
Barry Warsawd58d7641998-07-23 16:14:40 +00001464static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001465posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001466{
Victor Stinner8c62be82010-05-06 00:08:46 +00001467 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001468}
Mark Hammondef8b6542001-05-13 08:04:26 +00001469
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001470#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001471static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001472win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001473{
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 /* XXX We should pass the function name along in the future.
1475 (winreg.c also wants to pass the function name.)
1476 This would however require an additional param to the
1477 Windows error object, which is non-trivial.
1478 */
1479 errno = GetLastError();
1480 if (filename)
1481 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1482 else
1483 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001484}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001486static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001487win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001488{
1489 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001490 if (filename)
1491 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001492 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001493 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001494 filename);
1495 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001496 return PyErr_SetFromWindowsErr(err);
1497}
1498
1499static PyObject *
1500win32_error_object(const char* function, PyObject* filename)
1501{
1502 errno = GetLastError();
1503 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001504}
1505
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001506#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001507
Larry Hastings9cf065c2012-06-22 16:30:09 -07001508static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001509posix_path_object_error(PyObject *path)
1510{
1511 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1512}
1513
1514static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001515path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001516{
1517#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001518 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1519 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001520#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001521 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001522#endif
1523}
1524
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001525static PyObject *
1526path_object_error2(PyObject *path, PyObject *path2)
1527{
1528#ifdef MS_WINDOWS
1529 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1530 PyExc_OSError, 0, path, path2);
1531#else
1532 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1533#endif
1534}
1535
1536static PyObject *
1537path_error(path_t *path)
1538{
1539 return path_object_error(path->object);
1540}
Larry Hastings31826802013-10-19 00:09:25 -07001541
Larry Hastingsb0827312014-02-09 22:05:19 -08001542static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001543posix_path_error(path_t *path)
1544{
1545 return posix_path_object_error(path->object);
1546}
1547
1548static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001549path_error2(path_t *path, path_t *path2)
1550{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001551 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001552}
1553
1554
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001555/* POSIX generic methods */
1556
Larry Hastings2f936352014-08-05 14:04:04 +10001557static int
1558fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001559{
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001561 int *pointer = (int *)p;
1562 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001564 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001565 *pointer = fd;
1566 return 1;
1567}
1568
1569static PyObject *
1570posix_fildes_fd(int fd, int (*func)(int))
1571{
1572 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001573 int async_err = 0;
1574
1575 do {
1576 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001577 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001578 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001579 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001580 Py_END_ALLOW_THREADS
1581 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1582 if (res != 0)
1583 return (!async_err) ? posix_error() : NULL;
1584 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001585}
Guido van Rossum21142a01999-01-08 21:05:37 +00001586
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001587
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001588#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001589/* This is a reimplementation of the C library's chdir function,
1590 but one that produces Win32 errors instead of DOS error codes.
1591 chdir is essentially a wrapper around SetCurrentDirectory; however,
1592 it also needs to set "magic" environment variables indicating
1593 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001594static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001595win32_wchdir(LPCWSTR path)
1596{
Victor Stinnered537822015-12-13 21:40:26 +01001597 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001598 int result;
1599 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001600
Victor Stinner8c62be82010-05-06 00:08:46 +00001601 if(!SetCurrentDirectoryW(path))
1602 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001603 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 if (!result)
1605 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001606 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001607 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001608 if (!new_path) {
1609 SetLastError(ERROR_OUTOFMEMORY);
1610 return FALSE;
1611 }
1612 result = GetCurrentDirectoryW(result, new_path);
1613 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001614 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 return FALSE;
1616 }
1617 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001618 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1619 wcsncmp(new_path, L"//", 2) == 0);
1620 if (!is_unc_like_path) {
1621 env[1] = new_path[0];
1622 result = SetEnvironmentVariableW(env, new_path);
1623 }
Victor Stinnered537822015-12-13 21:40:26 +01001624 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001625 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001626 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001627}
1628#endif
1629
Martin v. Löwis14694662006-02-03 12:54:16 +00001630#ifdef MS_WINDOWS
1631/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1632 - time stamps are restricted to second resolution
1633 - file modification times suffer from forth-and-back conversions between
1634 UTC and local time
1635 Therefore, we implement our own stat, based on the Win32 API directly.
1636*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001637#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001638#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001639
Victor Stinner6036e442015-03-08 01:58:04 +01001640static void
Steve Dowercc16be82016-09-08 10:35:16 -07001641find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1642 BY_HANDLE_FILE_INFORMATION *info,
1643 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001644{
1645 memset(info, 0, sizeof(*info));
1646 info->dwFileAttributes = pFileData->dwFileAttributes;
1647 info->ftCreationTime = pFileData->ftCreationTime;
1648 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1649 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1650 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1651 info->nFileSizeLow = pFileData->nFileSizeLow;
1652/* info->nNumberOfLinks = 1; */
1653 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1654 *reparse_tag = pFileData->dwReserved0;
1655 else
1656 *reparse_tag = 0;
1657}
1658
Guido van Rossumd8faa362007-04-27 19:54:29 +00001659static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001660attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001661{
Victor Stinner8c62be82010-05-06 00:08:46 +00001662 HANDLE hFindFile;
1663 WIN32_FIND_DATAW FileData;
1664 hFindFile = FindFirstFileW(pszFile, &FileData);
1665 if (hFindFile == INVALID_HANDLE_VALUE)
1666 return FALSE;
1667 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001668 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001669 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001670}
1671
Brian Curtind25aef52011-06-13 15:16:04 -05001672static BOOL
1673get_target_path(HANDLE hdl, wchar_t **target_path)
1674{
1675 int buf_size, result_length;
1676 wchar_t *buf;
1677
1678 /* We have a good handle to the target, use it to determine
1679 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001680 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1681 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001682 if(!buf_size)
1683 return FALSE;
1684
Victor Stinnerc36674a2016-03-16 14:30:16 +01001685 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001686 if (!buf) {
1687 SetLastError(ERROR_OUTOFMEMORY);
1688 return FALSE;
1689 }
1690
Steve Dower2ea51c92015-03-20 21:49:12 -07001691 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001692 buf, buf_size, VOLUME_NAME_DOS);
1693
1694 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001695 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001696 return FALSE;
1697 }
1698
Brian Curtind25aef52011-06-13 15:16:04 -05001699 buf[result_length] = 0;
1700
1701 *target_path = buf;
1702 return TRUE;
1703}
1704
1705static int
Steve Dowercc16be82016-09-08 10:35:16 -07001706win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001707 BOOL traverse)
1708{
Victor Stinner26de69d2011-06-17 15:15:38 +02001709 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001710 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001711 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001712 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001713 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001714 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001715
Steve Dowercc16be82016-09-08 10:35:16 -07001716 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001718 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001719 0, /* share mode */
1720 NULL, /* security attributes */
1721 OPEN_EXISTING,
1722 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001723 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1724 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001725 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001726 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1727 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001728 NULL);
1729
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001730 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001731 /* Either the target doesn't exist, or we don't have access to
1732 get a handle to it. If the former, we need to return an error.
1733 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001734 DWORD lastError = GetLastError();
1735 if (lastError != ERROR_ACCESS_DENIED &&
1736 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001737 return -1;
1738 /* Could not get attributes on open file. Fall back to
1739 reading the directory. */
1740 if (!attributes_from_dir(path, &info, &reparse_tag))
1741 /* Very strange. This should not fail now */
1742 return -1;
1743 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1744 if (traverse) {
1745 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001746 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001747 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001749 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001750 } else {
1751 if (!GetFileInformationByHandle(hFile, &info)) {
1752 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001753 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001754 }
1755 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Mark Becwarb82bfac2019-02-02 16:08:23 -05001756 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1757 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001758 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001759 }
Brian Curtind25aef52011-06-13 15:16:04 -05001760 /* Close the outer open file handle now that we're about to
1761 reopen it with different flags. */
1762 if (!CloseHandle(hFile))
1763 return -1;
1764
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001766 /* In order to call GetFinalPathNameByHandle we need to open
1767 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001768 hFile2 = CreateFileW(
1769 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1770 NULL, OPEN_EXISTING,
1771 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1772 NULL);
1773 if (hFile2 == INVALID_HANDLE_VALUE)
1774 return -1;
1775
Mark Becwarb82bfac2019-02-02 16:08:23 -05001776 if (!get_target_path(hFile2, &target_path)) {
1777 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001778 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001779 }
1780
1781 if (!CloseHandle(hFile2)) {
1782 return -1;
1783 }
Brian Curtind25aef52011-06-13 15:16:04 -05001784
Steve Dowercc16be82016-09-08 10:35:16 -07001785 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001786 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001787 return code;
1788 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001789 } else
1790 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001791 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001792 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001793
1794 /* Set S_IEXEC if it is an .exe, .bat, ... */
1795 dot = wcsrchr(path, '.');
1796 if (dot) {
1797 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1798 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1799 result->st_mode |= 0111;
1800 }
1801 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001802}
1803
1804static int
Steve Dowercc16be82016-09-08 10:35:16 -07001805win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001806{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001807 /* Protocol violation: we explicitly clear errno, instead of
1808 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001809 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001810 errno = 0;
1811 return code;
1812}
Brian Curtind25aef52011-06-13 15:16:04 -05001813/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001814
1815 In Posix, stat automatically traverses symlinks and returns the stat
1816 structure for the target. In Windows, the equivalent GetFileAttributes by
1817 default does not traverse symlinks and instead returns attributes for
1818 the symlink.
1819
1820 Therefore, win32_lstat will get the attributes traditionally, and
1821 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001822 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001823
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001824static int
Steve Dowercc16be82016-09-08 10:35:16 -07001825win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001826{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001827 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001828}
1829
Victor Stinner8c62be82010-05-06 00:08:46 +00001830static int
Steve Dowercc16be82016-09-08 10:35:16 -07001831win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001832{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001833 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001834}
1835
Martin v. Löwis14694662006-02-03 12:54:16 +00001836#endif /* MS_WINDOWS */
1837
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001838PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001839"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001840This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001841 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001842or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1843\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001844Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1845or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001846\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001847See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001848
1849static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 {"st_mode", "protection bits"},
1851 {"st_ino", "inode"},
1852 {"st_dev", "device"},
1853 {"st_nlink", "number of hard links"},
1854 {"st_uid", "user ID of owner"},
1855 {"st_gid", "group ID of owner"},
1856 {"st_size", "total size, in bytes"},
1857 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1858 {NULL, "integer time of last access"},
1859 {NULL, "integer time of last modification"},
1860 {NULL, "integer time of last change"},
1861 {"st_atime", "time of last access"},
1862 {"st_mtime", "time of last modification"},
1863 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001864 {"st_atime_ns", "time of last access in nanoseconds"},
1865 {"st_mtime_ns", "time of last modification in nanoseconds"},
1866 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001867#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001868 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001869#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001870#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001872#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001873#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001874 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001875#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001876#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001877 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001878#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001879#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001880 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001881#endif
1882#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001884#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001885#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1886 {"st_file_attributes", "Windows file attribute bits"},
1887#endif
jcea6c51d512018-01-28 14:00:08 +01001888#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1889 {"st_fstype", "Type of filesystem"},
1890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001891 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001892};
1893
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001894#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001895#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001896#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001897#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001898#endif
1899
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001900#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001901#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1902#else
1903#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1904#endif
1905
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001906#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001907#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1908#else
1909#define ST_RDEV_IDX ST_BLOCKS_IDX
1910#endif
1911
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001912#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1913#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1914#else
1915#define ST_FLAGS_IDX ST_RDEV_IDX
1916#endif
1917
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001918#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001919#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001920#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001921#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001922#endif
1923
1924#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1925#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1926#else
1927#define ST_BIRTHTIME_IDX ST_GEN_IDX
1928#endif
1929
Zachary Ware63f277b2014-06-19 09:46:37 -05001930#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1931#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1932#else
1933#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1934#endif
1935
jcea6c51d512018-01-28 14:00:08 +01001936#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1937#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1938#else
1939#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1940#endif
1941
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 "stat_result", /* name */
1944 stat_result__doc__, /* doc */
1945 stat_result_fields,
1946 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001947};
1948
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001949PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001950"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1951This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001952 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001953or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001954\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001956
1957static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 {"f_bsize", },
1959 {"f_frsize", },
1960 {"f_blocks", },
1961 {"f_bfree", },
1962 {"f_bavail", },
1963 {"f_files", },
1964 {"f_ffree", },
1965 {"f_favail", },
1966 {"f_flag", },
1967 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001968 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001969 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001970};
1971
1972static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 "statvfs_result", /* name */
1974 statvfs_result__doc__, /* doc */
1975 statvfs_result_fields,
1976 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001977};
1978
Ross Lagerwall7807c352011-03-17 20:20:30 +02001979#if defined(HAVE_WAITID) && !defined(__APPLE__)
1980PyDoc_STRVAR(waitid_result__doc__,
1981"waitid_result: Result from waitid.\n\n\
1982This object may be accessed either as a tuple of\n\
1983 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1984or via the attributes si_pid, si_uid, and so on.\n\
1985\n\
1986See os.waitid for more information.");
1987
1988static PyStructSequence_Field waitid_result_fields[] = {
1989 {"si_pid", },
1990 {"si_uid", },
1991 {"si_signo", },
1992 {"si_status", },
1993 {"si_code", },
1994 {0}
1995};
1996
1997static PyStructSequence_Desc waitid_result_desc = {
1998 "waitid_result", /* name */
1999 waitid_result__doc__, /* doc */
2000 waitid_result_fields,
2001 5
2002};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002003static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02002004#endif
2005
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002006static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002007static PyTypeObject* StatResultType;
2008static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07002009#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002010static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002011#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002012static newfunc structseq_new;
2013
2014static PyObject *
2015statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2016{
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 PyStructSequence *result;
2018 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002019
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 result = (PyStructSequence*)structseq_new(type, args, kwds);
2021 if (!result)
2022 return NULL;
2023 /* If we have been initialized from a tuple,
2024 st_?time might be set to None. Initialize it
2025 from the int slots. */
2026 for (i = 7; i <= 9; i++) {
2027 if (result->ob_item[i+3] == Py_None) {
2028 Py_DECREF(Py_None);
2029 Py_INCREF(result->ob_item[i]);
2030 result->ob_item[i+3] = result->ob_item[i];
2031 }
2032 }
2033 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002034}
2035
2036
Larry Hastings6fe20b32012-04-19 15:07:49 -07002037static PyObject *billion = NULL;
2038
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002039static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002040fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002041{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002042 PyObject *s = _PyLong_FromTime_t(sec);
2043 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2044 PyObject *s_in_ns = NULL;
2045 PyObject *ns_total = NULL;
2046 PyObject *float_s = NULL;
2047
2048 if (!(s && ns_fractional))
2049 goto exit;
2050
2051 s_in_ns = PyNumber_Multiply(s, billion);
2052 if (!s_in_ns)
2053 goto exit;
2054
2055 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2056 if (!ns_total)
2057 goto exit;
2058
Victor Stinner01b5aab2017-10-24 02:02:00 -07002059 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2060 if (!float_s) {
2061 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002062 }
2063
2064 PyStructSequence_SET_ITEM(v, index, s);
2065 PyStructSequence_SET_ITEM(v, index+3, float_s);
2066 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2067 s = NULL;
2068 float_s = NULL;
2069 ns_total = NULL;
2070exit:
2071 Py_XDECREF(s);
2072 Py_XDECREF(ns_fractional);
2073 Py_XDECREF(s_in_ns);
2074 Py_XDECREF(ns_total);
2075 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002076}
2077
Tim Peters5aa91602002-01-30 05:46:57 +00002078/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002079 (used by posix_stat() and posix_fstat()) */
2080static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002081_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002082{
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002084 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 if (v == NULL)
2086 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002087
Victor Stinner8c62be82010-05-06 00:08:46 +00002088 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002089 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002090 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002091#ifdef MS_WINDOWS
2092 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002093#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002094 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002095#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002097#if defined(MS_WINDOWS)
2098 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2099 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2100#else
2101 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2102 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2103#endif
xdegaye50e86032017-05-22 11:15:08 +02002104 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2105 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002106
Martin v. Löwis14694662006-02-03 12:54:16 +00002107#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 ansec = st->st_atim.tv_nsec;
2109 mnsec = st->st_mtim.tv_nsec;
2110 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002111#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 ansec = st->st_atimespec.tv_nsec;
2113 mnsec = st->st_mtimespec.tv_nsec;
2114 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002115#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002116 ansec = st->st_atime_nsec;
2117 mnsec = st->st_mtime_nsec;
2118 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002119#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002120 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002121#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002122 fill_time(v, 7, st->st_atime, ansec);
2123 fill_time(v, 8, st->st_mtime, mnsec);
2124 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002125
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002126#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002127 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2128 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002129#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002130#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002131 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2132 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002133#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002134#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2136 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002137#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002138#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002139 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2140 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002141#endif
2142#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002143 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002144 PyObject *val;
2145 unsigned long bsec,bnsec;
2146 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002147#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002148 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002149#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002150 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002151#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002152 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002153 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2154 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002155 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002156#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002157#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002158 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2159 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002160#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002161#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2162 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2163 PyLong_FromUnsignedLong(st->st_file_attributes));
2164#endif
jcea6c51d512018-01-28 14:00:08 +01002165#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2166 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2167 PyUnicode_FromString(st->st_fstype));
2168#endif
Fred Drake699f3522000-06-29 21:12:41 +00002169
Victor Stinner8c62be82010-05-06 00:08:46 +00002170 if (PyErr_Occurred()) {
2171 Py_DECREF(v);
2172 return NULL;
2173 }
Fred Drake699f3522000-06-29 21:12:41 +00002174
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002176}
2177
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002178/* POSIX methods */
2179
Guido van Rossum94f6f721999-01-06 18:42:14 +00002180
2181static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002182posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002183 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002184{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002185 STRUCT_STAT st;
2186 int result;
2187
2188#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2189 if (follow_symlinks_specified(function_name, follow_symlinks))
2190 return NULL;
2191#endif
2192
2193 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2194 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2195 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2196 return NULL;
2197
2198 Py_BEGIN_ALLOW_THREADS
2199 if (path->fd != -1)
2200 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002201#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002202 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002203 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002204 else
Steve Dowercc16be82016-09-08 10:35:16 -07002205 result = win32_lstat(path->wide, &st);
2206#else
2207 else
2208#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002209 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2210 result = LSTAT(path->narrow, &st);
2211 else
Steve Dowercc16be82016-09-08 10:35:16 -07002212#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002213#ifdef HAVE_FSTATAT
2214 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2215 result = fstatat(dir_fd, path->narrow, &st,
2216 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2217 else
Steve Dowercc16be82016-09-08 10:35:16 -07002218#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002219 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002220#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002221 Py_END_ALLOW_THREADS
2222
Victor Stinner292c8352012-10-30 02:17:38 +01002223 if (result != 0) {
2224 return path_error(path);
2225 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002226
2227 return _pystat_fromstructstat(&st);
2228}
2229
Larry Hastings2f936352014-08-05 14:04:04 +10002230/*[python input]
2231
2232for s in """
2233
2234FACCESSAT
2235FCHMODAT
2236FCHOWNAT
2237FSTATAT
2238LINKAT
2239MKDIRAT
2240MKFIFOAT
2241MKNODAT
2242OPENAT
2243READLINKAT
2244SYMLINKAT
2245UNLINKAT
2246
2247""".strip().split():
2248 s = s.strip()
2249 print("""
2250#ifdef HAVE_{s}
2251 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002252#else
Larry Hastings2f936352014-08-05 14:04:04 +10002253 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002254#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002255""".rstrip().format(s=s))
2256
2257for s in """
2258
2259FCHDIR
2260FCHMOD
2261FCHOWN
2262FDOPENDIR
2263FEXECVE
2264FPATHCONF
2265FSTATVFS
2266FTRUNCATE
2267
2268""".strip().split():
2269 s = s.strip()
2270 print("""
2271#ifdef HAVE_{s}
2272 #define PATH_HAVE_{s} 1
2273#else
2274 #define PATH_HAVE_{s} 0
2275#endif
2276
2277""".rstrip().format(s=s))
2278[python start generated code]*/
2279
2280#ifdef HAVE_FACCESSAT
2281 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2282#else
2283 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2284#endif
2285
2286#ifdef HAVE_FCHMODAT
2287 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2288#else
2289 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2290#endif
2291
2292#ifdef HAVE_FCHOWNAT
2293 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2294#else
2295 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2296#endif
2297
2298#ifdef HAVE_FSTATAT
2299 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2300#else
2301 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2302#endif
2303
2304#ifdef HAVE_LINKAT
2305 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2306#else
2307 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2308#endif
2309
2310#ifdef HAVE_MKDIRAT
2311 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2312#else
2313 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2314#endif
2315
2316#ifdef HAVE_MKFIFOAT
2317 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2318#else
2319 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2320#endif
2321
2322#ifdef HAVE_MKNODAT
2323 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2324#else
2325 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2326#endif
2327
2328#ifdef HAVE_OPENAT
2329 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2330#else
2331 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2332#endif
2333
2334#ifdef HAVE_READLINKAT
2335 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2336#else
2337 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2338#endif
2339
2340#ifdef HAVE_SYMLINKAT
2341 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2342#else
2343 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2344#endif
2345
2346#ifdef HAVE_UNLINKAT
2347 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2348#else
2349 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2350#endif
2351
2352#ifdef HAVE_FCHDIR
2353 #define PATH_HAVE_FCHDIR 1
2354#else
2355 #define PATH_HAVE_FCHDIR 0
2356#endif
2357
2358#ifdef HAVE_FCHMOD
2359 #define PATH_HAVE_FCHMOD 1
2360#else
2361 #define PATH_HAVE_FCHMOD 0
2362#endif
2363
2364#ifdef HAVE_FCHOWN
2365 #define PATH_HAVE_FCHOWN 1
2366#else
2367 #define PATH_HAVE_FCHOWN 0
2368#endif
2369
2370#ifdef HAVE_FDOPENDIR
2371 #define PATH_HAVE_FDOPENDIR 1
2372#else
2373 #define PATH_HAVE_FDOPENDIR 0
2374#endif
2375
2376#ifdef HAVE_FEXECVE
2377 #define PATH_HAVE_FEXECVE 1
2378#else
2379 #define PATH_HAVE_FEXECVE 0
2380#endif
2381
2382#ifdef HAVE_FPATHCONF
2383 #define PATH_HAVE_FPATHCONF 1
2384#else
2385 #define PATH_HAVE_FPATHCONF 0
2386#endif
2387
2388#ifdef HAVE_FSTATVFS
2389 #define PATH_HAVE_FSTATVFS 1
2390#else
2391 #define PATH_HAVE_FSTATVFS 0
2392#endif
2393
2394#ifdef HAVE_FTRUNCATE
2395 #define PATH_HAVE_FTRUNCATE 1
2396#else
2397 #define PATH_HAVE_FTRUNCATE 0
2398#endif
2399/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002400
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002401#ifdef MS_WINDOWS
2402 #undef PATH_HAVE_FTRUNCATE
2403 #define PATH_HAVE_FTRUNCATE 1
2404#endif
Larry Hastings31826802013-10-19 00:09:25 -07002405
Larry Hastings61272b72014-01-07 12:41:53 -08002406/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002407
2408class path_t_converter(CConverter):
2409
2410 type = "path_t"
2411 impl_by_reference = True
2412 parse_by_reference = True
2413
2414 converter = 'path_converter'
2415
2416 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002417 # right now path_t doesn't support default values.
2418 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002419 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002420 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002421
Larry Hastings2f936352014-08-05 14:04:04 +10002422 if self.c_default not in (None, 'Py_None'):
2423 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002424
2425 self.nullable = nullable
2426 self.allow_fd = allow_fd
2427
Larry Hastings7726ac92014-01-31 22:03:12 -08002428 def pre_render(self):
2429 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002430 if isinstance(value, str):
2431 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002432 return str(int(bool(value)))
2433
2434 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002435 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002436 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002437 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002438 strify(self.nullable),
2439 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002440 )
2441
2442 def cleanup(self):
2443 return "path_cleanup(&" + self.name + ");\n"
2444
2445
2446class dir_fd_converter(CConverter):
2447 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002448
Larry Hastings2f936352014-08-05 14:04:04 +10002449 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002450 if self.default in (unspecified, None):
2451 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002452 if isinstance(requires, str):
2453 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2454 else:
2455 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002456
Larry Hastings2f936352014-08-05 14:04:04 +10002457class fildes_converter(CConverter):
2458 type = 'int'
2459 converter = 'fildes_converter'
2460
2461class uid_t_converter(CConverter):
2462 type = "uid_t"
2463 converter = '_Py_Uid_Converter'
2464
2465class gid_t_converter(CConverter):
2466 type = "gid_t"
2467 converter = '_Py_Gid_Converter'
2468
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002469class dev_t_converter(CConverter):
2470 type = 'dev_t'
2471 converter = '_Py_Dev_Converter'
2472
2473class dev_t_return_converter(unsigned_long_return_converter):
2474 type = 'dev_t'
2475 conversion_fn = '_PyLong_FromDev'
2476 unsigned_cast = '(dev_t)'
2477
Larry Hastings2f936352014-08-05 14:04:04 +10002478class FSConverter_converter(CConverter):
2479 type = 'PyObject *'
2480 converter = 'PyUnicode_FSConverter'
2481 def converter_init(self):
2482 if self.default is not unspecified:
2483 fail("FSConverter_converter does not support default values")
2484 self.c_default = 'NULL'
2485
2486 def cleanup(self):
2487 return "Py_XDECREF(" + self.name + ");\n"
2488
2489class pid_t_converter(CConverter):
2490 type = 'pid_t'
2491 format_unit = '" _Py_PARSE_PID "'
2492
2493class idtype_t_converter(int_converter):
2494 type = 'idtype_t'
2495
2496class id_t_converter(CConverter):
2497 type = 'id_t'
2498 format_unit = '" _Py_PARSE_PID "'
2499
Benjamin Petersonca470632016-09-06 13:47:26 -07002500class intptr_t_converter(CConverter):
2501 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002502 format_unit = '" _Py_PARSE_INTPTR "'
2503
2504class Py_off_t_converter(CConverter):
2505 type = 'Py_off_t'
2506 converter = 'Py_off_t_converter'
2507
2508class Py_off_t_return_converter(long_return_converter):
2509 type = 'Py_off_t'
2510 conversion_fn = 'PyLong_FromPy_off_t'
2511
2512class path_confname_converter(CConverter):
2513 type="int"
2514 converter="conv_path_confname"
2515
2516class confstr_confname_converter(path_confname_converter):
2517 converter='conv_confstr_confname'
2518
2519class sysconf_confname_converter(path_confname_converter):
2520 converter="conv_sysconf_confname"
2521
2522class sched_param_converter(CConverter):
2523 type = 'struct sched_param'
2524 converter = 'convert_sched_param'
2525 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002526
Larry Hastings61272b72014-01-07 12:41:53 -08002527[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002528/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002529
Larry Hastings61272b72014-01-07 12:41:53 -08002530/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002531
Larry Hastings2a727912014-01-16 11:32:01 -08002532os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002533
2534 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002535 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002536 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002537
2538 *
2539
Larry Hastings2f936352014-08-05 14:04:04 +10002540 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002541 If not None, it should be a file descriptor open to a directory,
2542 and path should be a relative string; path will then be relative to
2543 that directory.
2544
2545 follow_symlinks: bool = True
2546 If False, and the last element of the path is a symbolic link,
2547 stat will examine the symbolic link itself instead of the file
2548 the link points to.
2549
2550Perform a stat system call on the given path.
2551
2552dir_fd and follow_symlinks may not be implemented
2553 on your platform. If they are unavailable, using them will raise a
2554 NotImplementedError.
2555
2556It's an error to use dir_fd or follow_symlinks when specifying path as
2557 an open file descriptor.
2558
Larry Hastings61272b72014-01-07 12:41:53 -08002559[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002560
Larry Hastings31826802013-10-19 00:09:25 -07002561static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002562os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002563/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002564{
2565 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2566}
2567
Larry Hastings2f936352014-08-05 14:04:04 +10002568
2569/*[clinic input]
2570os.lstat
2571
2572 path : path_t
2573
2574 *
2575
2576 dir_fd : dir_fd(requires='fstatat') = None
2577
2578Perform a stat system call on the given path, without following symbolic links.
2579
2580Like stat(), but do not follow symbolic links.
2581Equivalent to stat(path, follow_symlinks=False).
2582[clinic start generated code]*/
2583
Larry Hastings2f936352014-08-05 14:04:04 +10002584static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002585os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2586/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002587{
2588 int follow_symlinks = 0;
2589 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2590}
Larry Hastings31826802013-10-19 00:09:25 -07002591
Larry Hastings2f936352014-08-05 14:04:04 +10002592
Larry Hastings61272b72014-01-07 12:41:53 -08002593/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002594os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002595
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002596 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002597 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002598
2599 mode: int
2600 Operating-system mode bitfield. Can be F_OK to test existence,
2601 or the inclusive-OR of R_OK, W_OK, and X_OK.
2602
2603 *
2604
Larry Hastings2f936352014-08-05 14:04:04 +10002605 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002606 If not None, it should be a file descriptor open to a directory,
2607 and path should be relative; path will then be relative to that
2608 directory.
2609
2610 effective_ids: bool = False
2611 If True, access will use the effective uid/gid instead of
2612 the real uid/gid.
2613
2614 follow_symlinks: bool = True
2615 If False, and the last element of the path is a symbolic link,
2616 access will examine the symbolic link itself instead of the file
2617 the link points to.
2618
2619Use the real uid/gid to test for access to a path.
2620
2621{parameters}
2622dir_fd, effective_ids, and follow_symlinks may not be implemented
2623 on your platform. If they are unavailable, using them will raise a
2624 NotImplementedError.
2625
2626Note that most operations will use the effective uid/gid, therefore this
2627 routine can be used in a suid/sgid environment to test if the invoking user
2628 has the specified access to the path.
2629
Larry Hastings61272b72014-01-07 12:41:53 -08002630[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002631
Larry Hastings2f936352014-08-05 14:04:04 +10002632static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002633os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002634 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002635/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002636{
Larry Hastings2f936352014-08-05 14:04:04 +10002637 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002638
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002639#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002640 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002641#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002643#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644
Larry Hastings9cf065c2012-06-22 16:30:09 -07002645#ifndef HAVE_FACCESSAT
2646 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002647 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648
2649 if (effective_ids) {
2650 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002651 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652 }
2653#endif
2654
2655#ifdef MS_WINDOWS
2656 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002657 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002658 Py_END_ALLOW_THREADS
2659
2660 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002661 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002662 * * we didn't get a -1, and
2663 * * write access wasn't requested,
2664 * * or the file isn't read-only,
2665 * * or it's a directory.
2666 * (Directories cannot be read-only on Windows.)
2667 */
Larry Hastings2f936352014-08-05 14:04:04 +10002668 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002669 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002670 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002671 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002672#else
2673
2674 Py_BEGIN_ALLOW_THREADS
2675#ifdef HAVE_FACCESSAT
2676 if ((dir_fd != DEFAULT_DIR_FD) ||
2677 effective_ids ||
2678 !follow_symlinks) {
2679 int flags = 0;
2680 if (!follow_symlinks)
2681 flags |= AT_SYMLINK_NOFOLLOW;
2682 if (effective_ids)
2683 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002684 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002685 }
2686 else
2687#endif
Larry Hastings31826802013-10-19 00:09:25 -07002688 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002690 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002691#endif
2692
Larry Hastings9cf065c2012-06-22 16:30:09 -07002693 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002694}
2695
Guido van Rossumd371ff11999-01-25 16:12:23 +00002696#ifndef F_OK
2697#define F_OK 0
2698#endif
2699#ifndef R_OK
2700#define R_OK 4
2701#endif
2702#ifndef W_OK
2703#define W_OK 2
2704#endif
2705#ifndef X_OK
2706#define X_OK 1
2707#endif
2708
Larry Hastings31826802013-10-19 00:09:25 -07002709
Guido van Rossumd371ff11999-01-25 16:12:23 +00002710#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002711/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002712os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002713
2714 fd: int
2715 Integer file descriptor handle.
2716
2717 /
2718
2719Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002720[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002721
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002723os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002724/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002725{
2726 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002727
Larry Hastings31826802013-10-19 00:09:25 -07002728 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002729 if (ret == NULL) {
2730 return posix_error();
2731 }
2732 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002733}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002734#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002735
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002736#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002737/*[clinic input]
2738os.ctermid
2739
2740Return the name of the controlling terminal for this process.
2741[clinic start generated code]*/
2742
Larry Hastings2f936352014-08-05 14:04:04 +10002743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002744os_ctermid_impl(PyObject *module)
2745/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002746{
Victor Stinner8c62be82010-05-06 00:08:46 +00002747 char *ret;
2748 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002749
Greg Wardb48bc172000-03-01 21:51:56 +00002750#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002751 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002752#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002753 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002754#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002755 if (ret == NULL)
2756 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002757 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002758}
Larry Hastings2f936352014-08-05 14:04:04 +10002759#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002760
Larry Hastings2f936352014-08-05 14:04:04 +10002761
2762/*[clinic input]
2763os.chdir
2764
2765 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2766
2767Change the current working directory to the specified path.
2768
2769path may always be specified as a string.
2770On some platforms, path may also be specified as an open file descriptor.
2771 If this functionality is unavailable, using it raises an exception.
2772[clinic start generated code]*/
2773
Larry Hastings2f936352014-08-05 14:04:04 +10002774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002775os_chdir_impl(PyObject *module, path_t *path)
2776/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002777{
2778 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002779
2780 Py_BEGIN_ALLOW_THREADS
2781#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002782 /* on unix, success = 0, on windows, success = !0 */
2783 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#else
2785#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002786 if (path->fd != -1)
2787 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788 else
2789#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002790 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002791#endif
2792 Py_END_ALLOW_THREADS
2793
2794 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002795 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002796 }
2797
Larry Hastings2f936352014-08-05 14:04:04 +10002798 Py_RETURN_NONE;
2799}
2800
2801
2802#ifdef HAVE_FCHDIR
2803/*[clinic input]
2804os.fchdir
2805
2806 fd: fildes
2807
2808Change to the directory of the given file descriptor.
2809
2810fd must be opened on a directory, not a file.
2811Equivalent to os.chdir(fd).
2812
2813[clinic start generated code]*/
2814
Fred Drake4d1e64b2002-04-15 19:40:07 +00002815static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002816os_fchdir_impl(PyObject *module, int fd)
2817/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002818{
Larry Hastings2f936352014-08-05 14:04:04 +10002819 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002820}
2821#endif /* HAVE_FCHDIR */
2822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002823
Larry Hastings2f936352014-08-05 14:04:04 +10002824/*[clinic input]
2825os.chmod
2826
2827 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002828 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002829 On some platforms, path may also be specified as an open file descriptor.
2830 If this functionality is unavailable, using it raises an exception.
2831
2832 mode: int
2833 Operating-system mode bitfield.
2834
2835 *
2836
2837 dir_fd : dir_fd(requires='fchmodat') = None
2838 If not None, it should be a file descriptor open to a directory,
2839 and path should be relative; path will then be relative to that
2840 directory.
2841
2842 follow_symlinks: bool = True
2843 If False, and the last element of the path is a symbolic link,
2844 chmod will modify the symbolic link itself instead of the file
2845 the link points to.
2846
2847Change the access permissions of a file.
2848
2849It is an error to use dir_fd or follow_symlinks when specifying path as
2850 an open file descriptor.
2851dir_fd and follow_symlinks may not be implemented on your platform.
2852 If they are unavailable, using them will raise a NotImplementedError.
2853
2854[clinic start generated code]*/
2855
Larry Hastings2f936352014-08-05 14:04:04 +10002856static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002857os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002858 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002859/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002860{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002862
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002863#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002864 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002866
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867#ifdef HAVE_FCHMODAT
2868 int fchmodat_nofollow_unsupported = 0;
2869#endif
2870
Larry Hastings9cf065c2012-06-22 16:30:09 -07002871#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2872 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002873 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002874#endif
2875
2876#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002877 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002878 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002879 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880 result = 0;
2881 else {
2882 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002883 attr &= ~FILE_ATTRIBUTE_READONLY;
2884 else
2885 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002886 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887 }
2888 Py_END_ALLOW_THREADS
2889
2890 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002891 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892 }
2893#else /* MS_WINDOWS */
2894 Py_BEGIN_ALLOW_THREADS
2895#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002896 if (path->fd != -1)
2897 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002898 else
2899#endif
2900#ifdef HAVE_LCHMOD
2901 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002902 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002903 else
2904#endif
2905#ifdef HAVE_FCHMODAT
2906 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2907 /*
2908 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2909 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002910 * and then says it isn't implemented yet.
2911 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002912 *
2913 * Once it is supported, os.chmod will automatically
2914 * support dir_fd and follow_symlinks=False. (Hopefully.)
2915 * Until then, we need to be careful what exception we raise.
2916 */
Larry Hastings2f936352014-08-05 14:04:04 +10002917 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002918 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2919 /*
2920 * But wait! We can't throw the exception without allowing threads,
2921 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2922 */
2923 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002924 result &&
2925 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2926 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 }
2928 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002929#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002930 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002931 Py_END_ALLOW_THREADS
2932
2933 if (result) {
2934#ifdef HAVE_FCHMODAT
2935 if (fchmodat_nofollow_unsupported) {
2936 if (dir_fd != DEFAULT_DIR_FD)
2937 dir_fd_and_follow_symlinks_invalid("chmod",
2938 dir_fd, follow_symlinks);
2939 else
2940 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002941 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002942 }
2943 else
2944#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002945 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002946 }
2947#endif
2948
Larry Hastings2f936352014-08-05 14:04:04 +10002949 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002950}
2951
Larry Hastings9cf065c2012-06-22 16:30:09 -07002952
Christian Heimes4e30a842007-11-30 22:12:06 +00002953#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002954/*[clinic input]
2955os.fchmod
2956
2957 fd: int
2958 mode: int
2959
2960Change the access permissions of the file given by file descriptor fd.
2961
2962Equivalent to os.chmod(fd, mode).
2963[clinic start generated code]*/
2964
Larry Hastings2f936352014-08-05 14:04:04 +10002965static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002966os_fchmod_impl(PyObject *module, int fd, int mode)
2967/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002968{
2969 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002970 int async_err = 0;
2971
2972 do {
2973 Py_BEGIN_ALLOW_THREADS
2974 res = fchmod(fd, mode);
2975 Py_END_ALLOW_THREADS
2976 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2977 if (res != 0)
2978 return (!async_err) ? posix_error() : NULL;
2979
Victor Stinner8c62be82010-05-06 00:08:46 +00002980 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002981}
2982#endif /* HAVE_FCHMOD */
2983
Larry Hastings2f936352014-08-05 14:04:04 +10002984
Christian Heimes4e30a842007-11-30 22:12:06 +00002985#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002986/*[clinic input]
2987os.lchmod
2988
2989 path: path_t
2990 mode: int
2991
2992Change the access permissions of a file, without following symbolic links.
2993
2994If path is a symlink, this affects the link itself rather than the target.
2995Equivalent to chmod(path, mode, follow_symlinks=False)."
2996[clinic start generated code]*/
2997
Larry Hastings2f936352014-08-05 14:04:04 +10002998static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002999os_lchmod_impl(PyObject *module, path_t *path, int mode)
3000/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003001{
Victor Stinner8c62be82010-05-06 00:08:46 +00003002 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003003 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003004 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003005 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003006 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003007 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003008 return NULL;
3009 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003011}
3012#endif /* HAVE_LCHMOD */
3013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Thomas Wouterscf297e42007-02-23 15:07:44 +00003015#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003016/*[clinic input]
3017os.chflags
3018
3019 path: path_t
3020 flags: unsigned_long(bitwise=True)
3021 follow_symlinks: bool=True
3022
3023Set file flags.
3024
3025If follow_symlinks is False, and the last element of the path is a symbolic
3026 link, chflags will change flags on the symbolic link itself instead of the
3027 file the link points to.
3028follow_symlinks may not be implemented on your platform. If it is
3029unavailable, using it will raise a NotImplementedError.
3030
3031[clinic start generated code]*/
3032
Larry Hastings2f936352014-08-05 14:04:04 +10003033static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003034os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003035 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003036/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003037{
3038 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003039
3040#ifndef HAVE_LCHFLAGS
3041 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003042 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003043#endif
3044
Victor Stinner8c62be82010-05-06 00:08:46 +00003045 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003046#ifdef HAVE_LCHFLAGS
3047 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003048 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003049 else
3050#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003051 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003052 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003053
Larry Hastings2f936352014-08-05 14:04:04 +10003054 if (result)
3055 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056
Larry Hastings2f936352014-08-05 14:04:04 +10003057 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003058}
3059#endif /* HAVE_CHFLAGS */
3060
Larry Hastings2f936352014-08-05 14:04:04 +10003061
Thomas Wouterscf297e42007-02-23 15:07:44 +00003062#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003063/*[clinic input]
3064os.lchflags
3065
3066 path: path_t
3067 flags: unsigned_long(bitwise=True)
3068
3069Set file flags.
3070
3071This function will not follow symbolic links.
3072Equivalent to chflags(path, flags, follow_symlinks=False).
3073[clinic start generated code]*/
3074
Larry Hastings2f936352014-08-05 14:04:04 +10003075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003076os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3077/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003078{
Victor Stinner8c62be82010-05-06 00:08:46 +00003079 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003080 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003081 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003082 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003083 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003084 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003085 }
Victor Stinner292c8352012-10-30 02:17:38 +01003086 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003087}
3088#endif /* HAVE_LCHFLAGS */
3089
Larry Hastings2f936352014-08-05 14:04:04 +10003090
Martin v. Löwis244edc82001-10-04 22:44:26 +00003091#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003092/*[clinic input]
3093os.chroot
3094 path: path_t
3095
3096Change root directory to path.
3097
3098[clinic start generated code]*/
3099
Larry Hastings2f936352014-08-05 14:04:04 +10003100static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003101os_chroot_impl(PyObject *module, path_t *path)
3102/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003103{
3104 int res;
3105 Py_BEGIN_ALLOW_THREADS
3106 res = chroot(path->narrow);
3107 Py_END_ALLOW_THREADS
3108 if (res < 0)
3109 return path_error(path);
3110 Py_RETURN_NONE;
3111}
3112#endif /* HAVE_CHROOT */
3113
Martin v. Löwis244edc82001-10-04 22:44:26 +00003114
Guido van Rossum21142a01999-01-08 21:05:37 +00003115#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003116/*[clinic input]
3117os.fsync
3118
3119 fd: fildes
3120
3121Force write of fd to disk.
3122[clinic start generated code]*/
3123
Larry Hastings2f936352014-08-05 14:04:04 +10003124static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003125os_fsync_impl(PyObject *module, int fd)
3126/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003127{
3128 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003129}
3130#endif /* HAVE_FSYNC */
3131
Larry Hastings2f936352014-08-05 14:04:04 +10003132
Ross Lagerwall7807c352011-03-17 20:20:30 +02003133#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003134/*[clinic input]
3135os.sync
3136
3137Force write of everything to disk.
3138[clinic start generated code]*/
3139
Larry Hastings2f936352014-08-05 14:04:04 +10003140static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003141os_sync_impl(PyObject *module)
3142/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003143{
3144 Py_BEGIN_ALLOW_THREADS
3145 sync();
3146 Py_END_ALLOW_THREADS
3147 Py_RETURN_NONE;
3148}
Larry Hastings2f936352014-08-05 14:04:04 +10003149#endif /* HAVE_SYNC */
3150
Ross Lagerwall7807c352011-03-17 20:20:30 +02003151
Guido van Rossum21142a01999-01-08 21:05:37 +00003152#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003153#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003154extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3155#endif
3156
Larry Hastings2f936352014-08-05 14:04:04 +10003157/*[clinic input]
3158os.fdatasync
3159
3160 fd: fildes
3161
3162Force write of fd to disk without forcing update of metadata.
3163[clinic start generated code]*/
3164
Larry Hastings2f936352014-08-05 14:04:04 +10003165static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003166os_fdatasync_impl(PyObject *module, int fd)
3167/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003168{
3169 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003170}
3171#endif /* HAVE_FDATASYNC */
3172
3173
Fredrik Lundh10723342000-07-10 16:38:09 +00003174#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003175/*[clinic input]
3176os.chown
3177
3178 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003179 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003180
3181 uid: uid_t
3182
3183 gid: gid_t
3184
3185 *
3186
3187 dir_fd : dir_fd(requires='fchownat') = None
3188 If not None, it should be a file descriptor open to a directory,
3189 and path should be relative; path will then be relative to that
3190 directory.
3191
3192 follow_symlinks: bool = True
3193 If False, and the last element of the path is a symbolic link,
3194 stat will examine the symbolic link itself instead of the file
3195 the link points to.
3196
3197Change the owner and group id of path to the numeric uid and gid.\
3198
3199path may always be specified as a string.
3200On some platforms, path may also be specified as an open file descriptor.
3201 If this functionality is unavailable, using it raises an exception.
3202If dir_fd is not None, it should be a file descriptor open to a directory,
3203 and path should be relative; path will then be relative to that directory.
3204If follow_symlinks is False, and the last element of the path is a symbolic
3205 link, chown will modify the symbolic link itself instead of the file the
3206 link points to.
3207It is an error to use dir_fd or follow_symlinks when specifying path as
3208 an open file descriptor.
3209dir_fd and follow_symlinks may not be implemented on your platform.
3210 If they are unavailable, using them will raise a NotImplementedError.
3211
3212[clinic start generated code]*/
3213
Larry Hastings2f936352014-08-05 14:04:04 +10003214static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003215os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003216 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003217/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003218{
3219 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220
3221#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3222 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003223 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003224#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003225 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3226 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3227 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003228
3229#ifdef __APPLE__
3230 /*
3231 * This is for Mac OS X 10.3, which doesn't have lchown.
3232 * (But we still have an lchown symbol because of weak-linking.)
3233 * It doesn't have fchownat either. So there's no possibility
3234 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003235 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003236 if ((!follow_symlinks) && (lchown == NULL)) {
3237 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003238 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003239 }
3240#endif
3241
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003244 if (path->fd != -1)
3245 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003246 else
3247#endif
3248#ifdef HAVE_LCHOWN
3249 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003250 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003251 else
3252#endif
3253#ifdef HAVE_FCHOWNAT
3254 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003255 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3257 else
3258#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003259 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261
Larry Hastings2f936352014-08-05 14:04:04 +10003262 if (result)
3263 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003264
Larry Hastings2f936352014-08-05 14:04:04 +10003265 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003266}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003267#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003268
Larry Hastings2f936352014-08-05 14:04:04 +10003269
Christian Heimes4e30a842007-11-30 22:12:06 +00003270#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003271/*[clinic input]
3272os.fchown
3273
3274 fd: int
3275 uid: uid_t
3276 gid: gid_t
3277
3278Change the owner and group id of the file specified by file descriptor.
3279
3280Equivalent to os.chown(fd, uid, gid).
3281
3282[clinic start generated code]*/
3283
Larry Hastings2f936352014-08-05 14:04:04 +10003284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003285os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3286/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003287{
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003289 int async_err = 0;
3290
3291 do {
3292 Py_BEGIN_ALLOW_THREADS
3293 res = fchown(fd, uid, gid);
3294 Py_END_ALLOW_THREADS
3295 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3296 if (res != 0)
3297 return (!async_err) ? posix_error() : NULL;
3298
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003300}
3301#endif /* HAVE_FCHOWN */
3302
Larry Hastings2f936352014-08-05 14:04:04 +10003303
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003304#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003305/*[clinic input]
3306os.lchown
3307
3308 path : path_t
3309 uid: uid_t
3310 gid: gid_t
3311
3312Change the owner and group id of path to the numeric uid and gid.
3313
3314This function will not follow symbolic links.
3315Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3316[clinic start generated code]*/
3317
Larry Hastings2f936352014-08-05 14:04:04 +10003318static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003319os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3320/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003321{
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003324 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003325 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003326 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003327 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003328 }
Larry Hastings2f936352014-08-05 14:04:04 +10003329 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003330}
3331#endif /* HAVE_LCHOWN */
3332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003333
Barry Warsaw53699e91996-12-10 23:23:01 +00003334static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003335posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003336{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003337 char *buf, *tmpbuf;
3338 char *cwd;
3339 const size_t chunk = 1024;
3340 size_t buflen = 0;
3341 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003342
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003343#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003344 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003345 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 wchar_t *wbuf2 = wbuf;
3347 PyObject *resobj;
3348 DWORD len;
3349 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003350 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003351 /* If the buffer is large enough, len does not include the
3352 terminating \0. If the buffer is too small, len includes
3353 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003354 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003355 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 if (wbuf2)
3357 len = GetCurrentDirectoryW(len, wbuf2);
3358 }
3359 Py_END_ALLOW_THREADS
3360 if (!wbuf2) {
3361 PyErr_NoMemory();
3362 return NULL;
3363 }
3364 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003365 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003366 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003367 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 }
3369 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003370 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003371 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 return resobj;
3373 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003374
3375 if (win32_warn_bytes_api())
3376 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003377#endif
3378
Victor Stinner4403d7d2015-04-25 00:16:10 +02003379 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003381 do {
3382 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003383#ifdef MS_WINDOWS
3384 if (buflen > INT_MAX) {
3385 PyErr_NoMemory();
3386 break;
3387 }
3388#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003389 tmpbuf = PyMem_RawRealloc(buf, buflen);
3390 if (tmpbuf == NULL)
3391 break;
3392
3393 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003394#ifdef MS_WINDOWS
3395 cwd = getcwd(buf, (int)buflen);
3396#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003397 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003398#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003399 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003401
3402 if (cwd == NULL) {
3403 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003405 }
3406
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003408 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3409 else
3410 obj = PyUnicode_DecodeFSDefault(buf);
3411 PyMem_RawFree(buf);
3412
3413 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003414}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003415
Larry Hastings2f936352014-08-05 14:04:04 +10003416
3417/*[clinic input]
3418os.getcwd
3419
3420Return a unicode string representing the current working directory.
3421[clinic start generated code]*/
3422
Larry Hastings2f936352014-08-05 14:04:04 +10003423static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003424os_getcwd_impl(PyObject *module)
3425/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003426{
3427 return posix_getcwd(0);
3428}
3429
Larry Hastings2f936352014-08-05 14:04:04 +10003430
3431/*[clinic input]
3432os.getcwdb
3433
3434Return a bytes string representing the current working directory.
3435[clinic start generated code]*/
3436
Larry Hastings2f936352014-08-05 14:04:04 +10003437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003438os_getcwdb_impl(PyObject *module)
3439/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003440{
3441 return posix_getcwd(1);
3442}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003443
Larry Hastings2f936352014-08-05 14:04:04 +10003444
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3446#define HAVE_LINK 1
3447#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003448
Guido van Rossumb6775db1994-08-01 11:34:53 +00003449#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003450/*[clinic input]
3451
3452os.link
3453
3454 src : path_t
3455 dst : path_t
3456 *
3457 src_dir_fd : dir_fd = None
3458 dst_dir_fd : dir_fd = None
3459 follow_symlinks: bool = True
3460
3461Create a hard link to a file.
3462
3463If either src_dir_fd or dst_dir_fd is not None, it should be a file
3464 descriptor open to a directory, and the respective path string (src or dst)
3465 should be relative; the path will then be relative to that directory.
3466If follow_symlinks is False, and the last element of src is a symbolic
3467 link, link will create a link to the symbolic link itself instead of the
3468 file the link points to.
3469src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3470 platform. If they are unavailable, using them will raise a
3471 NotImplementedError.
3472[clinic start generated code]*/
3473
Larry Hastings2f936352014-08-05 14:04:04 +10003474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003475os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003476 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003477/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003478{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003480 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481#else
3482 int result;
3483#endif
3484
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485#ifndef HAVE_LINKAT
3486 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3487 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003488 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 }
3490#endif
3491
Steve Dowercc16be82016-09-08 10:35:16 -07003492#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003493 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 PyErr_SetString(PyExc_NotImplementedError,
3495 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003496 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 }
Steve Dowercc16be82016-09-08 10:35:16 -07003498#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003499
Brian Curtin1b9df392010-11-24 20:24:31 +00003500#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003502 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003504
Larry Hastings2f936352014-08-05 14:04:04 +10003505 if (!result)
3506 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507#else
3508 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003509#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3511 (dst_dir_fd != DEFAULT_DIR_FD) ||
3512 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003513 result = linkat(src_dir_fd, src->narrow,
3514 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003515 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3516 else
Steve Dowercc16be82016-09-08 10:35:16 -07003517#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003518 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003520
Larry Hastings2f936352014-08-05 14:04:04 +10003521 if (result)
3522 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003523#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524
Larry Hastings2f936352014-08-05 14:04:04 +10003525 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003526}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527#endif
3528
Brian Curtin1b9df392010-11-24 20:24:31 +00003529
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003530#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003531static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003532_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003533{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 PyObject *v;
3535 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3536 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003537 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003539 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541
Steve Dowercc16be82016-09-08 10:35:16 -07003542 WIN32_FIND_DATAW wFileData;
3543 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003544
Steve Dowercc16be82016-09-08 10:35:16 -07003545 if (!path->wide) { /* Default arg: "." */
3546 po_wchars = L".";
3547 len = 1;
3548 } else {
3549 po_wchars = path->wide;
3550 len = wcslen(path->wide);
3551 }
3552 /* The +5 is so we can append "\\*.*\0" */
3553 wnamebuf = PyMem_New(wchar_t, len + 5);
3554 if (!wnamebuf) {
3555 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 }
Steve Dowercc16be82016-09-08 10:35:16 -07003558 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003560 wchar_t wch = wnamebuf[len-1];
3561 if (wch != SEP && wch != ALTSEP && wch != L':')
3562 wnamebuf[len++] = SEP;
3563 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 }
Steve Dowercc16be82016-09-08 10:35:16 -07003565 if ((list = PyList_New(0)) == NULL) {
3566 goto exit;
3567 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003568 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003569 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003570 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 if (hFindFile == INVALID_HANDLE_VALUE) {
3572 int error = GetLastError();
3573 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 goto exit;
3575 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003576 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 }
3579 do {
3580 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003581 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3582 wcscmp(wFileData.cFileName, L"..") != 0) {
3583 v = PyUnicode_FromWideChar(wFileData.cFileName,
3584 wcslen(wFileData.cFileName));
3585 if (path->narrow && v) {
3586 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3587 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 Py_DECREF(list);
3590 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 break;
3592 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003593 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595 Py_DECREF(list);
3596 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 break;
3598 }
3599 Py_DECREF(v);
3600 }
3601 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003602 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 Py_END_ALLOW_THREADS
3604 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3605 it got to the end of the directory. */
3606 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003608 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 }
3611 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003612
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613exit:
3614 if (hFindFile != INVALID_HANDLE_VALUE) {
3615 if (FindClose(hFindFile) == FALSE) {
3616 if (list != NULL) {
3617 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003618 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619 }
3620 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003622 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003623
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003625} /* end of _listdir_windows_no_opendir */
3626
3627#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3628
3629static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003630_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003631{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003632 PyObject *v;
3633 DIR *dirp = NULL;
3634 struct dirent *ep;
3635 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003636#ifdef HAVE_FDOPENDIR
3637 int fd = -1;
3638#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003639
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003642 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003643 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003644 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003645 if (fd == -1)
3646 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647
Larry Hastingsfdaea062012-06-25 04:42:23 -07003648 return_str = 1;
3649
Larry Hastings9cf065c2012-06-22 16:30:09 -07003650 Py_BEGIN_ALLOW_THREADS
3651 dirp = fdopendir(fd);
3652 Py_END_ALLOW_THREADS
3653 }
3654 else
3655#endif
3656 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003657 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003658 if (path->narrow) {
3659 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003660 /* only return bytes if they specified a bytes-like object */
3661 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003662 }
3663 else {
3664 name = ".";
3665 return_str = 1;
3666 }
3667
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668 Py_BEGIN_ALLOW_THREADS
3669 dirp = opendir(name);
3670 Py_END_ALLOW_THREADS
3671 }
3672
3673 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003674 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003675#ifdef HAVE_FDOPENDIR
3676 if (fd != -1) {
3677 Py_BEGIN_ALLOW_THREADS
3678 close(fd);
3679 Py_END_ALLOW_THREADS
3680 }
3681#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003682 goto exit;
3683 }
3684 if ((list = PyList_New(0)) == NULL) {
3685 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 }
3687 for (;;) {
3688 errno = 0;
3689 Py_BEGIN_ALLOW_THREADS
3690 ep = readdir(dirp);
3691 Py_END_ALLOW_THREADS
3692 if (ep == NULL) {
3693 if (errno == 0) {
3694 break;
3695 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003697 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 }
3700 }
3701 if (ep->d_name[0] == '.' &&
3702 (NAMLEN(ep) == 1 ||
3703 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3704 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003705 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003706 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3707 else
3708 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 break;
3712 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003715 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003716 break;
3717 }
3718 Py_DECREF(v);
3719 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003720
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721exit:
3722 if (dirp != NULL) {
3723 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003724#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003725 if (fd > -1)
3726 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003727#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 closedir(dirp);
3729 Py_END_ALLOW_THREADS
3730 }
3731
Larry Hastings9cf065c2012-06-22 16:30:09 -07003732 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003733} /* end of _posix_listdir */
3734#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003735
Larry Hastings2f936352014-08-05 14:04:04 +10003736
3737/*[clinic input]
3738os.listdir
3739
3740 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3741
3742Return a list containing the names of the files in the directory.
3743
BNMetricsb9427072018-11-02 15:20:19 +00003744path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003745 the filenames returned will also be bytes; in all other circumstances
3746 the filenames returned will be str.
3747If path is None, uses the path='.'.
3748On some platforms, path may also be specified as an open file descriptor;\
3749 the file descriptor must refer to a directory.
3750 If this functionality is unavailable, using it raises NotImplementedError.
3751
3752The list is in arbitrary order. It does not include the special
3753entries '.' and '..' even if they are present in the directory.
3754
3755
3756[clinic start generated code]*/
3757
Larry Hastings2f936352014-08-05 14:04:04 +10003758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003759os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003760/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003761{
Steve Dower60419a72019-06-24 08:42:54 -07003762 if (PySys_Audit("os.listdir", "O",
3763 path->object ? path->object : Py_None) < 0) {
3764 return NULL;
3765 }
Larry Hastings2f936352014-08-05 14:04:04 +10003766#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3767 return _listdir_windows_no_opendir(path, NULL);
3768#else
3769 return _posix_listdir(path, NULL);
3770#endif
3771}
3772
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003773#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003774/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003775/*[clinic input]
3776os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003777
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003778 path: path_t
3779 /
3780
3781[clinic start generated code]*/
3782
3783static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003784os__getfullpathname_impl(PyObject *module, path_t *path)
3785/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003786{
Steve Dowercc16be82016-09-08 10:35:16 -07003787 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3788 wchar_t *wtemp;
3789 DWORD result;
3790 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003791
Steve Dowercc16be82016-09-08 10:35:16 -07003792 result = GetFullPathNameW(path->wide,
3793 Py_ARRAY_LENGTH(woutbuf),
3794 woutbuf, &wtemp);
3795 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3796 woutbufp = PyMem_New(wchar_t, result);
3797 if (!woutbufp)
3798 return PyErr_NoMemory();
3799 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003800 }
Steve Dowercc16be82016-09-08 10:35:16 -07003801 if (result) {
3802 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3803 if (path->narrow)
3804 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3805 } else
3806 v = win32_error_object("GetFullPathNameW", path->object);
3807 if (woutbufp != woutbuf)
3808 PyMem_Free(woutbufp);
3809 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003810}
Brian Curtind40e6f72010-07-08 21:39:08 +00003811
Brian Curtind25aef52011-06-13 15:16:04 -05003812
Larry Hastings2f936352014-08-05 14:04:04 +10003813/*[clinic input]
3814os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003815
Steve Dower23ad6d02018-02-22 10:39:10 -08003816 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003817 /
3818
3819A helper function for samepath on windows.
3820[clinic start generated code]*/
3821
Larry Hastings2f936352014-08-05 14:04:04 +10003822static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003823os__getfinalpathname_impl(PyObject *module, path_t *path)
3824/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003825{
3826 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003827 wchar_t buf[MAXPATHLEN], *target_path = buf;
3828 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003829 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003830 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003831
Steve Dower23ad6d02018-02-22 10:39:10 -08003832 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003833 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003834 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003835 0, /* desired access */
3836 0, /* share mode */
3837 NULL, /* security attributes */
3838 OPEN_EXISTING,
3839 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3840 FILE_FLAG_BACKUP_SEMANTICS,
3841 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003842 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003843
Steve Dower23ad6d02018-02-22 10:39:10 -08003844 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003845 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003846 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003847
3848 /* We have a good handle to the target, use it to determine the
3849 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003850 while (1) {
3851 Py_BEGIN_ALLOW_THREADS
3852 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3853 buf_size, VOLUME_NAME_DOS);
3854 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003855
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003856 if (!result_length) {
3857 result = win32_error_object("GetFinalPathNameByHandleW",
3858 path->object);
3859 goto cleanup;
3860 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003861
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003862 if (result_length < buf_size) {
3863 break;
3864 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003865
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003866 wchar_t *tmp;
3867 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3868 result_length * sizeof(*tmp));
3869 if (!tmp) {
3870 result = PyErr_NoMemory();
3871 goto cleanup;
3872 }
3873
3874 buf_size = result_length;
3875 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003876 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003877
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003878 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003879 if (path->narrow)
3880 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003881
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003882cleanup:
3883 if (target_path != buf) {
3884 PyMem_Free(target_path);
3885 }
3886 CloseHandle(hFile);
3887 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003888}
Brian Curtin62857742010-09-06 17:07:27 +00003889
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003890/*[clinic input]
3891os._isdir
3892
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003893 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003894 /
3895
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003896Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003897[clinic start generated code]*/
3898
Brian Curtin9c669cc2011-06-08 18:17:18 -05003899static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003900os__isdir(PyObject *module, PyObject *arg)
3901/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003902{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003903 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003904 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3905
3906 if (!path_converter(arg, &path)) {
3907 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3908 PyErr_Clear();
3909 Py_RETURN_FALSE;
3910 }
3911 return NULL;
3912 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003913
Steve Dowerb22a6772016-07-17 20:49:38 -07003914 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003915 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003916 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003917
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003918 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003919 if (attributes == INVALID_FILE_ATTRIBUTES)
3920 Py_RETURN_FALSE;
3921
Brian Curtin9c669cc2011-06-08 18:17:18 -05003922 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3923 Py_RETURN_TRUE;
3924 else
3925 Py_RETURN_FALSE;
3926}
Tim Golden6b528062013-08-01 12:44:00 +01003927
Tim Golden6b528062013-08-01 12:44:00 +01003928
Larry Hastings2f936352014-08-05 14:04:04 +10003929/*[clinic input]
3930os._getvolumepathname
3931
Steve Dower23ad6d02018-02-22 10:39:10 -08003932 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003933
3934A helper function for ismount on Win32.
3935[clinic start generated code]*/
3936
Larry Hastings2f936352014-08-05 14:04:04 +10003937static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003938os__getvolumepathname_impl(PyObject *module, path_t *path)
3939/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003940{
3941 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003942 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003943 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003944 BOOL ret;
3945
Tim Golden6b528062013-08-01 12:44:00 +01003946 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003947 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003948
Victor Stinner850a18e2017-10-24 16:53:32 -07003949 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003950 PyErr_SetString(PyExc_OverflowError, "path too long");
3951 return NULL;
3952 }
3953
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003954 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003955 if (mountpath == NULL)
3956 return PyErr_NoMemory();
3957
3958 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003959 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003960 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003961 Py_END_ALLOW_THREADS
3962
3963 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003964 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003965 goto exit;
3966 }
3967 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003968 if (path->narrow)
3969 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003970
3971exit:
3972 PyMem_Free(mountpath);
3973 return result;
3974}
Tim Golden6b528062013-08-01 12:44:00 +01003975
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003976#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003977
Larry Hastings2f936352014-08-05 14:04:04 +10003978
3979/*[clinic input]
3980os.mkdir
3981
3982 path : path_t
3983
3984 mode: int = 0o777
3985
3986 *
3987
3988 dir_fd : dir_fd(requires='mkdirat') = None
3989
3990# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3991
3992Create a directory.
3993
3994If dir_fd is not None, it should be a file descriptor open to a directory,
3995 and path should be relative; path will then be relative to that directory.
3996dir_fd may not be implemented on your platform.
3997 If it is unavailable, using it will raise a NotImplementedError.
3998
3999The mode argument is ignored on Windows.
4000[clinic start generated code]*/
4001
Larry Hastings2f936352014-08-05 14:04:04 +10004002static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004003os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4004/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004005{
4006 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004007
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004008#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004010 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004012
Larry Hastings2f936352014-08-05 14:04:04 +10004013 if (!result)
4014 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004015#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004017#if HAVE_MKDIRAT
4018 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004019 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004020 else
4021#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004022#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004023 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004024#else
Larry Hastings2f936352014-08-05 14:04:04 +10004025 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004026#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004027 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004028 if (result < 0)
4029 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004030#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004031 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004032}
4033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004034
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004035/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4036#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004037#include <sys/resource.h>
4038#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004039
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004040
4041#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004042/*[clinic input]
4043os.nice
4044
4045 increment: int
4046 /
4047
4048Add increment to the priority of process and return the new priority.
4049[clinic start generated code]*/
4050
Larry Hastings2f936352014-08-05 14:04:04 +10004051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004052os_nice_impl(PyObject *module, int increment)
4053/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004054{
4055 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004056
Victor Stinner8c62be82010-05-06 00:08:46 +00004057 /* There are two flavours of 'nice': one that returns the new
4058 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004059 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004061
Victor Stinner8c62be82010-05-06 00:08:46 +00004062 If we are of the nice family that returns the new priority, we
4063 need to clear errno before the call, and check if errno is filled
4064 before calling posix_error() on a returnvalue of -1, because the
4065 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004066
Victor Stinner8c62be82010-05-06 00:08:46 +00004067 errno = 0;
4068 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004069#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004070 if (value == 0)
4071 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004072#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004073 if (value == -1 && errno != 0)
4074 /* either nice() or getpriority() returned an error */
4075 return posix_error();
4076 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004077}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004078#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004079
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004080
4081#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004082/*[clinic input]
4083os.getpriority
4084
4085 which: int
4086 who: int
4087
4088Return program scheduling priority.
4089[clinic start generated code]*/
4090
Larry Hastings2f936352014-08-05 14:04:04 +10004091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004092os_getpriority_impl(PyObject *module, int which, int who)
4093/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004094{
4095 int retval;
4096
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004097 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004098 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004099 if (errno != 0)
4100 return posix_error();
4101 return PyLong_FromLong((long)retval);
4102}
4103#endif /* HAVE_GETPRIORITY */
4104
4105
4106#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004107/*[clinic input]
4108os.setpriority
4109
4110 which: int
4111 who: int
4112 priority: int
4113
4114Set program scheduling priority.
4115[clinic start generated code]*/
4116
Larry Hastings2f936352014-08-05 14:04:04 +10004117static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004118os_setpriority_impl(PyObject *module, int which, int who, int priority)
4119/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004120{
4121 int retval;
4122
4123 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004124 if (retval == -1)
4125 return posix_error();
4126 Py_RETURN_NONE;
4127}
4128#endif /* HAVE_SETPRIORITY */
4129
4130
Barry Warsaw53699e91996-12-10 23:23:01 +00004131static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004132internal_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 +00004133{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004134 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004137#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004138 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004139 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004140#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004142#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143
Larry Hastings9cf065c2012-06-22 16:30:09 -07004144 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4145 (dst_dir_fd != DEFAULT_DIR_FD);
4146#ifndef HAVE_RENAMEAT
4147 if (dir_fd_specified) {
4148 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004149 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 }
4151#endif
4152
Larry Hastings9cf065c2012-06-22 16:30:09 -07004153#ifdef MS_WINDOWS
4154 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004155 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004156 Py_END_ALLOW_THREADS
4157
Larry Hastings2f936352014-08-05 14:04:04 +10004158 if (!result)
4159 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160
4161#else
Steve Dowercc16be82016-09-08 10:35:16 -07004162 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4163 PyErr_Format(PyExc_ValueError,
4164 "%s: src and dst must be the same type", function_name);
4165 return NULL;
4166 }
4167
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168 Py_BEGIN_ALLOW_THREADS
4169#ifdef HAVE_RENAMEAT
4170 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004171 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172 else
4173#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004174 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004175 Py_END_ALLOW_THREADS
4176
Larry Hastings2f936352014-08-05 14:04:04 +10004177 if (result)
4178 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004179#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004180 Py_RETURN_NONE;
4181}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004182
Larry Hastings2f936352014-08-05 14:04:04 +10004183
4184/*[clinic input]
4185os.rename
4186
4187 src : path_t
4188 dst : path_t
4189 *
4190 src_dir_fd : dir_fd = None
4191 dst_dir_fd : dir_fd = None
4192
4193Rename a file or directory.
4194
4195If either src_dir_fd or dst_dir_fd is not None, it should be a file
4196 descriptor open to a directory, and the respective path string (src or dst)
4197 should be relative; the path will then be relative to that directory.
4198src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4199 If they are unavailable, using them will raise a NotImplementedError.
4200[clinic start generated code]*/
4201
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004202static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004203os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004204 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004205/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004206{
Larry Hastings2f936352014-08-05 14:04:04 +10004207 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004208}
4209
Larry Hastings2f936352014-08-05 14:04:04 +10004210
4211/*[clinic input]
4212os.replace = os.rename
4213
4214Rename a file or directory, overwriting the destination.
4215
4216If either src_dir_fd or dst_dir_fd is not None, it should be a file
4217 descriptor open to a directory, and the respective path string (src or dst)
4218 should be relative; the path will then be relative to that directory.
4219src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004220 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004221[clinic start generated code]*/
4222
Larry Hastings2f936352014-08-05 14:04:04 +10004223static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004224os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4225 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004226/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004227{
4228 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4229}
4230
4231
4232/*[clinic input]
4233os.rmdir
4234
4235 path: path_t
4236 *
4237 dir_fd: dir_fd(requires='unlinkat') = None
4238
4239Remove a directory.
4240
4241If dir_fd is not None, it should be a file descriptor open to a directory,
4242 and path should be relative; path will then be relative to that directory.
4243dir_fd may not be implemented on your platform.
4244 If it is unavailable, using it will raise a NotImplementedError.
4245[clinic start generated code]*/
4246
Larry Hastings2f936352014-08-05 14:04:04 +10004247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004248os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4249/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004250{
4251 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004252
4253 Py_BEGIN_ALLOW_THREADS
4254#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004255 /* Windows, success=1, UNIX, success=0 */
4256 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004257#else
4258#ifdef HAVE_UNLINKAT
4259 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004260 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004261 else
4262#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004263 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004264#endif
4265 Py_END_ALLOW_THREADS
4266
Larry Hastings2f936352014-08-05 14:04:04 +10004267 if (result)
4268 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004269
Larry Hastings2f936352014-08-05 14:04:04 +10004270 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004271}
4272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004273
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004274#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004275#ifdef MS_WINDOWS
4276/*[clinic input]
4277os.system -> long
4278
4279 command: Py_UNICODE
4280
4281Execute the command in a subshell.
4282[clinic start generated code]*/
4283
Larry Hastings2f936352014-08-05 14:04:04 +10004284static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004285os_system_impl(PyObject *module, const Py_UNICODE *command)
4286/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004287{
4288 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004289
4290 if (PySys_Audit("system", "(u)", command) < 0) {
4291 return -1;
4292 }
4293
Victor Stinner8c62be82010-05-06 00:08:46 +00004294 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004295 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004296 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004297 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004298 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004299 return result;
4300}
4301#else /* MS_WINDOWS */
4302/*[clinic input]
4303os.system -> long
4304
4305 command: FSConverter
4306
4307Execute the command in a subshell.
4308[clinic start generated code]*/
4309
Larry Hastings2f936352014-08-05 14:04:04 +10004310static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004311os_system_impl(PyObject *module, PyObject *command)
4312/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004313{
4314 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004315 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004316
4317 if (PySys_Audit("system", "(O)", command) < 0) {
4318 return -1;
4319 }
4320
Larry Hastings2f936352014-08-05 14:04:04 +10004321 Py_BEGIN_ALLOW_THREADS
4322 result = system(bytes);
4323 Py_END_ALLOW_THREADS
4324 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004325}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004326#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004327#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Larry Hastings2f936352014-08-05 14:04:04 +10004330/*[clinic input]
4331os.umask
4332
4333 mask: int
4334 /
4335
4336Set the current numeric umask and return the previous umask.
4337[clinic start generated code]*/
4338
Larry Hastings2f936352014-08-05 14:04:04 +10004339static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004340os_umask_impl(PyObject *module, int mask)
4341/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004342{
4343 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004344 if (i < 0)
4345 return posix_error();
4346 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004347}
4348
Brian Curtind40e6f72010-07-08 21:39:08 +00004349#ifdef MS_WINDOWS
4350
4351/* override the default DeleteFileW behavior so that directory
4352symlinks can be removed with this function, the same as with
4353Unix symlinks */
4354BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4355{
4356 WIN32_FILE_ATTRIBUTE_DATA info;
4357 WIN32_FIND_DATAW find_data;
4358 HANDLE find_data_handle;
4359 int is_directory = 0;
4360 int is_link = 0;
4361
4362 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4363 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004364
Brian Curtind40e6f72010-07-08 21:39:08 +00004365 /* Get WIN32_FIND_DATA structure for the path to determine if
4366 it is a symlink */
4367 if(is_directory &&
4368 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4369 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4370
4371 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004372 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4373 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4374 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4375 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004376 FindClose(find_data_handle);
4377 }
4378 }
4379 }
4380
4381 if (is_directory && is_link)
4382 return RemoveDirectoryW(lpFileName);
4383
4384 return DeleteFileW(lpFileName);
4385}
4386#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004387
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004388
Larry Hastings2f936352014-08-05 14:04:04 +10004389/*[clinic input]
4390os.unlink
4391
4392 path: path_t
4393 *
4394 dir_fd: dir_fd(requires='unlinkat')=None
4395
4396Remove a file (same as remove()).
4397
4398If dir_fd is not None, it should be a file descriptor open to a directory,
4399 and path should be relative; path will then be relative to that directory.
4400dir_fd may not be implemented on your platform.
4401 If it is unavailable, using it will raise a NotImplementedError.
4402
4403[clinic start generated code]*/
4404
Larry Hastings2f936352014-08-05 14:04:04 +10004405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004406os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4407/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004408{
4409 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004410
4411 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004412 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004413#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004414 /* Windows, success=1, UNIX, success=0 */
4415 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004416#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004417#ifdef HAVE_UNLINKAT
4418 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004419 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004420 else
4421#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004422 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004423#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004424 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004425 Py_END_ALLOW_THREADS
4426
Larry Hastings2f936352014-08-05 14:04:04 +10004427 if (result)
4428 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004429
Larry Hastings2f936352014-08-05 14:04:04 +10004430 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004431}
4432
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004433
Larry Hastings2f936352014-08-05 14:04:04 +10004434/*[clinic input]
4435os.remove = os.unlink
4436
4437Remove a file (same as unlink()).
4438
4439If dir_fd is not None, it should be a file descriptor open to a directory,
4440 and path should be relative; path will then be relative to that directory.
4441dir_fd may not be implemented on your platform.
4442 If it is unavailable, using it will raise a NotImplementedError.
4443[clinic start generated code]*/
4444
Larry Hastings2f936352014-08-05 14:04:04 +10004445static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004446os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4447/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004448{
4449 return os_unlink_impl(module, path, dir_fd);
4450}
4451
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004452
Larry Hastings605a62d2012-06-24 04:33:36 -07004453static PyStructSequence_Field uname_result_fields[] = {
4454 {"sysname", "operating system name"},
4455 {"nodename", "name of machine on network (implementation-defined)"},
4456 {"release", "operating system release"},
4457 {"version", "operating system version"},
4458 {"machine", "hardware identifier"},
4459 {NULL}
4460};
4461
4462PyDoc_STRVAR(uname_result__doc__,
4463"uname_result: Result from os.uname().\n\n\
4464This object may be accessed either as a tuple of\n\
4465 (sysname, nodename, release, version, machine),\n\
4466or via the attributes sysname, nodename, release, version, and machine.\n\
4467\n\
4468See os.uname for more information.");
4469
4470static PyStructSequence_Desc uname_result_desc = {
4471 "uname_result", /* name */
4472 uname_result__doc__, /* doc */
4473 uname_result_fields,
4474 5
4475};
4476
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004477static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004478
4479
4480#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004481/*[clinic input]
4482os.uname
4483
4484Return an object identifying the current operating system.
4485
4486The object behaves like a named tuple with the following fields:
4487 (sysname, nodename, release, version, machine)
4488
4489[clinic start generated code]*/
4490
Larry Hastings2f936352014-08-05 14:04:04 +10004491static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004492os_uname_impl(PyObject *module)
4493/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004494{
Victor Stinner8c62be82010-05-06 00:08:46 +00004495 struct utsname u;
4496 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004497 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004498
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 Py_BEGIN_ALLOW_THREADS
4500 res = uname(&u);
4501 Py_END_ALLOW_THREADS
4502 if (res < 0)
4503 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004504
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004505 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004506 if (value == NULL)
4507 return NULL;
4508
4509#define SET(i, field) \
4510 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004511 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004512 if (!o) { \
4513 Py_DECREF(value); \
4514 return NULL; \
4515 } \
4516 PyStructSequence_SET_ITEM(value, i, o); \
4517 } \
4518
4519 SET(0, u.sysname);
4520 SET(1, u.nodename);
4521 SET(2, u.release);
4522 SET(3, u.version);
4523 SET(4, u.machine);
4524
4525#undef SET
4526
4527 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004528}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004529#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004530
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004531
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532
4533typedef struct {
4534 int now;
4535 time_t atime_s;
4536 long atime_ns;
4537 time_t mtime_s;
4538 long mtime_ns;
4539} utime_t;
4540
4541/*
Victor Stinner484df002014-10-09 13:52:31 +02004542 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543 * they also intentionally leak the declaration of a pointer named "time"
4544 */
4545#define UTIME_TO_TIMESPEC \
4546 struct timespec ts[2]; \
4547 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004548 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 time = NULL; \
4550 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004551 ts[0].tv_sec = ut->atime_s; \
4552 ts[0].tv_nsec = ut->atime_ns; \
4553 ts[1].tv_sec = ut->mtime_s; \
4554 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555 time = ts; \
4556 } \
4557
4558#define UTIME_TO_TIMEVAL \
4559 struct timeval tv[2]; \
4560 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004561 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562 time = NULL; \
4563 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004564 tv[0].tv_sec = ut->atime_s; \
4565 tv[0].tv_usec = ut->atime_ns / 1000; \
4566 tv[1].tv_sec = ut->mtime_s; \
4567 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004568 time = tv; \
4569 } \
4570
4571#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004572 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004573 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004574 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 time = NULL; \
4576 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004577 u.actime = ut->atime_s; \
4578 u.modtime = ut->mtime_s; \
4579 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580 }
4581
4582#define UTIME_TO_TIME_T \
4583 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004584 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004585 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586 time = NULL; \
4587 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004588 timet[0] = ut->atime_s; \
4589 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004590 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 } \
4592
4593
Victor Stinner528a9ab2015-09-03 21:30:26 +02004594#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595
4596static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004597utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598{
4599#ifdef HAVE_UTIMENSAT
4600 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4601 UTIME_TO_TIMESPEC;
4602 return utimensat(dir_fd, path, time, flags);
4603#elif defined(HAVE_FUTIMESAT)
4604 UTIME_TO_TIMEVAL;
4605 /*
4606 * follow_symlinks will never be false here;
4607 * we only allow !follow_symlinks and dir_fd together
4608 * if we have utimensat()
4609 */
4610 assert(follow_symlinks);
4611 return futimesat(dir_fd, path, time);
4612#endif
4613}
4614
Larry Hastings2f936352014-08-05 14:04:04 +10004615 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4616#else
4617 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004618#endif
4619
Victor Stinner528a9ab2015-09-03 21:30:26 +02004620#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621
4622static int
Victor Stinner484df002014-10-09 13:52:31 +02004623utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624{
4625#ifdef HAVE_FUTIMENS
4626 UTIME_TO_TIMESPEC;
4627 return futimens(fd, time);
4628#else
4629 UTIME_TO_TIMEVAL;
4630 return futimes(fd, time);
4631#endif
4632}
4633
Larry Hastings2f936352014-08-05 14:04:04 +10004634 #define PATH_UTIME_HAVE_FD 1
4635#else
4636 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637#endif
4638
Victor Stinner5ebae872015-09-22 01:29:33 +02004639#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4640# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4641#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642
Victor Stinner4552ced2015-09-21 22:37:15 +02004643#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004644
4645static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004646utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647{
4648#ifdef HAVE_UTIMENSAT
4649 UTIME_TO_TIMESPEC;
4650 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4651#else
4652 UTIME_TO_TIMEVAL;
4653 return lutimes(path, time);
4654#endif
4655}
4656
4657#endif
4658
4659#ifndef MS_WINDOWS
4660
4661static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004662utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663{
4664#ifdef HAVE_UTIMENSAT
4665 UTIME_TO_TIMESPEC;
4666 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4667#elif defined(HAVE_UTIMES)
4668 UTIME_TO_TIMEVAL;
4669 return utimes(path, time);
4670#elif defined(HAVE_UTIME_H)
4671 UTIME_TO_UTIMBUF;
4672 return utime(path, time);
4673#else
4674 UTIME_TO_TIME_T;
4675 return utime(path, time);
4676#endif
4677}
4678
4679#endif
4680
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681static int
4682split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4683{
4684 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004685 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004686 divmod = PyNumber_Divmod(py_long, billion);
4687 if (!divmod)
4688 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004689 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4690 PyErr_Format(PyExc_TypeError,
4691 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4692 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4693 goto exit;
4694 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004695 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4696 if ((*s == -1) && PyErr_Occurred())
4697 goto exit;
4698 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004699 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004700 goto exit;
4701
4702 result = 1;
4703exit:
4704 Py_XDECREF(divmod);
4705 return result;
4706}
4707
Larry Hastings2f936352014-08-05 14:04:04 +10004708
4709/*[clinic input]
4710os.utime
4711
4712 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4713 times: object = NULL
4714 *
4715 ns: object = NULL
4716 dir_fd: dir_fd(requires='futimensat') = None
4717 follow_symlinks: bool=True
4718
Martin Panter0ff89092015-09-09 01:56:53 +00004719# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004720
4721Set the access and modified time of path.
4722
4723path may always be specified as a string.
4724On some platforms, path may also be specified as an open file descriptor.
4725 If this functionality is unavailable, using it raises an exception.
4726
4727If times is not None, it must be a tuple (atime, mtime);
4728 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004729If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004730 atime_ns and mtime_ns should be expressed as integer nanoseconds
4731 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004732If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004733Specifying tuples for both times and ns is an error.
4734
4735If dir_fd is not None, it should be a file descriptor open to a directory,
4736 and path should be relative; path will then be relative to that directory.
4737If follow_symlinks is False, and the last element of the path is a symbolic
4738 link, utime will modify the symbolic link itself instead of the file the
4739 link points to.
4740It is an error to use dir_fd or follow_symlinks when specifying path
4741 as an open file descriptor.
4742dir_fd and follow_symlinks may not be available on your platform.
4743 If they are unavailable, using them will raise a NotImplementedError.
4744
4745[clinic start generated code]*/
4746
Larry Hastings2f936352014-08-05 14:04:04 +10004747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004748os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4749 int dir_fd, int follow_symlinks)
4750/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004751{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752#ifdef MS_WINDOWS
4753 HANDLE hFile;
4754 FILETIME atime, mtime;
4755#else
4756 int result;
4757#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004758
Larry Hastings2f936352014-08-05 14:04:04 +10004759 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004760
Christian Heimesb3c87242013-08-01 00:08:16 +02004761 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004762
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 if (times && (times != Py_None) && ns) {
4764 PyErr_SetString(PyExc_ValueError,
4765 "utime: you may specify either 'times'"
4766 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004767 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004768 }
4769
4770 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004771 time_t a_sec, m_sec;
4772 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004773 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774 PyErr_SetString(PyExc_TypeError,
4775 "utime: 'times' must be either"
4776 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004777 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004778 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004780 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004781 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004782 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004783 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004784 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004785 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004786 utime.atime_s = a_sec;
4787 utime.atime_ns = a_nsec;
4788 utime.mtime_s = m_sec;
4789 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004790 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004792 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793 PyErr_SetString(PyExc_TypeError,
4794 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004795 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004796 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004797 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004798 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004800 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004802 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004803 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 }
4805 else {
4806 /* times and ns are both None/unspecified. use "now". */
4807 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004808 }
4809
Victor Stinner4552ced2015-09-21 22:37:15 +02004810#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004812 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004814
Larry Hastings2f936352014-08-05 14:04:04 +10004815 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4816 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4817 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004818 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004819
Larry Hastings9cf065c2012-06-22 16:30:09 -07004820#if !defined(HAVE_UTIMENSAT)
4821 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004822 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004823 "utime: cannot use dir_fd and follow_symlinks "
4824 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004825 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004826 }
4827#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004828
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004829#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004831 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4832 NULL, OPEN_EXISTING,
4833 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834 Py_END_ALLOW_THREADS
4835 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004836 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004837 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004838 }
4839
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004841 GetSystemTimeAsFileTime(&mtime);
4842 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004844 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004845 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4846 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 }
4848 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4849 /* Avoid putting the file name into the error here,
4850 as that may confuse the user into believing that
4851 something is wrong with the file, when it also
4852 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004853 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004854 CloseHandle(hFile);
4855 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004857 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004858#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004859 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004860
Victor Stinner4552ced2015-09-21 22:37:15 +02004861#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004863 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004864 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004865#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004866
Victor Stinner528a9ab2015-09-03 21:30:26 +02004867#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004868 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004869 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004870 else
4871#endif
4872
Victor Stinner528a9ab2015-09-03 21:30:26 +02004873#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004874 if (path->fd != -1)
4875 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004876 else
4877#endif
4878
Larry Hastings2f936352014-08-05 14:04:04 +10004879 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004880
4881 Py_END_ALLOW_THREADS
4882
4883 if (result < 0) {
4884 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004885 posix_error();
4886 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004887 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004888
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004889#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004890
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004891 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004892}
4893
Guido van Rossum3b066191991-06-04 19:40:25 +00004894/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004895
Larry Hastings2f936352014-08-05 14:04:04 +10004896
4897/*[clinic input]
4898os._exit
4899
4900 status: int
4901
4902Exit to the system with specified status, without normal exit processing.
4903[clinic start generated code]*/
4904
Larry Hastings2f936352014-08-05 14:04:04 +10004905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004906os__exit_impl(PyObject *module, int status)
4907/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004908{
4909 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004910 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004911}
4912
Steve Dowercc16be82016-09-08 10:35:16 -07004913#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4914#define EXECV_CHAR wchar_t
4915#else
4916#define EXECV_CHAR char
4917#endif
4918
pxinwrf2d7ac72019-05-21 18:46:37 +08004919#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004920static void
Steve Dowercc16be82016-09-08 10:35:16 -07004921free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004922{
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 Py_ssize_t i;
4924 for (i = 0; i < count; i++)
4925 PyMem_Free(array[i]);
4926 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004927}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004928
Berker Peksag81816462016-09-15 20:19:47 +03004929static int
4930fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004931{
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004933 PyObject *ub;
4934 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004935#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004936 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004937 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004938 *out = PyUnicode_AsWideCharString(ub, &size);
4939 if (*out)
4940 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004941#else
Berker Peksag81816462016-09-15 20:19:47 +03004942 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004943 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004944 size = PyBytes_GET_SIZE(ub);
4945 *out = PyMem_Malloc(size + 1);
4946 if (*out) {
4947 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4948 result = 1;
4949 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004950 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004951#endif
Berker Peksag81816462016-09-15 20:19:47 +03004952 Py_DECREF(ub);
4953 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004954}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004955#endif
4956
pxinwrf2d7ac72019-05-21 18:46:37 +08004957#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07004958static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004959parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4960{
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 Py_ssize_t i, pos, envc;
4962 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004963 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004964 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004965
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 i = PyMapping_Size(env);
4967 if (i < 0)
4968 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004969 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 if (envlist == NULL) {
4971 PyErr_NoMemory();
4972 return NULL;
4973 }
4974 envc = 0;
4975 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004976 if (!keys)
4977 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004979 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 goto error;
4981 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4982 PyErr_Format(PyExc_TypeError,
4983 "env.keys() or env.values() is not a list");
4984 goto error;
4985 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004986
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 for (pos = 0; pos < i; pos++) {
4988 key = PyList_GetItem(keys, pos);
4989 val = PyList_GetItem(vals, pos);
4990 if (!key || !val)
4991 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004992
Berker Peksag81816462016-09-15 20:19:47 +03004993#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4994 if (!PyUnicode_FSDecoder(key, &key2))
4995 goto error;
4996 if (!PyUnicode_FSDecoder(val, &val2)) {
4997 Py_DECREF(key2);
4998 goto error;
4999 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005000 /* Search from index 1 because on Windows starting '=' is allowed for
5001 defining hidden environment variables. */
5002 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5003 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5004 {
5005 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005006 Py_DECREF(key2);
5007 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005008 goto error;
5009 }
Berker Peksag81816462016-09-15 20:19:47 +03005010 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5011#else
5012 if (!PyUnicode_FSConverter(key, &key2))
5013 goto error;
5014 if (!PyUnicode_FSConverter(val, &val2)) {
5015 Py_DECREF(key2);
5016 goto error;
5017 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005018 if (PyBytes_GET_SIZE(key2) == 0 ||
5019 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5020 {
5021 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005022 Py_DECREF(key2);
5023 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005024 goto error;
5025 }
Berker Peksag81816462016-09-15 20:19:47 +03005026 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5027 PyBytes_AS_STRING(val2));
5028#endif
5029 Py_DECREF(key2);
5030 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005031 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005033
5034 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5035 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 goto error;
5037 }
Berker Peksag81816462016-09-15 20:19:47 +03005038
Steve Dowercc16be82016-09-08 10:35:16 -07005039 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 }
5041 Py_DECREF(vals);
5042 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005043
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 envlist[envc] = 0;
5045 *envc_ptr = envc;
5046 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005047
5048error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 Py_XDECREF(keys);
5050 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005051 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005052 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005053}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Steve Dowercc16be82016-09-08 10:35:16 -07005055static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056parse_arglist(PyObject* argv, Py_ssize_t *argc)
5057{
5058 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005059 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005060 if (argvlist == NULL) {
5061 PyErr_NoMemory();
5062 return NULL;
5063 }
5064 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005065 PyObject* item = PySequence_ITEM(argv, i);
5066 if (item == NULL)
5067 goto fail;
5068 if (!fsconvert_strdup(item, &argvlist[i])) {
5069 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070 goto fail;
5071 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005072 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005073 }
5074 argvlist[*argc] = NULL;
5075 return argvlist;
5076fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005077 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005078 free_string_array(argvlist, *argc);
5079 return NULL;
5080}
Steve Dowercc16be82016-09-08 10:35:16 -07005081
Ross Lagerwall7807c352011-03-17 20:20:30 +02005082#endif
5083
Larry Hastings2f936352014-08-05 14:04:04 +10005084
Ross Lagerwall7807c352011-03-17 20:20:30 +02005085#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005086/*[clinic input]
5087os.execv
5088
Steve Dowercc16be82016-09-08 10:35:16 -07005089 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005090 Path of executable file.
5091 argv: object
5092 Tuple or list of strings.
5093 /
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 *
Steve Dowercc16be82016-09-08 10:35:16 -07005099os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5100/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005101{
Steve Dowercc16be82016-09-08 10:35:16 -07005102 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005103 Py_ssize_t argc;
5104
5105 /* execv has two arguments: (path, argv), where
5106 argv is a list or tuple of strings. */
5107
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5109 PyErr_SetString(PyExc_TypeError,
5110 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 return NULL;
5112 }
5113 argc = PySequence_Size(argv);
5114 if (argc < 1) {
5115 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 return NULL;
5117 }
5118
5119 argvlist = parse_arglist(argv, &argc);
5120 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005121 return NULL;
5122 }
Steve Dowerbce26262016-11-19 19:17:26 -08005123 if (!argvlist[0][0]) {
5124 PyErr_SetString(PyExc_ValueError,
5125 "execv() arg 2 first element cannot be empty");
5126 free_string_array(argvlist, argc);
5127 return NULL;
5128 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005129
Steve Dowerbce26262016-11-19 19:17:26 -08005130 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005131#ifdef HAVE_WEXECV
5132 _wexecv(path->wide, argvlist);
5133#else
5134 execv(path->narrow, argvlist);
5135#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005136 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005137
5138 /* If we get here it's definitely an error */
5139
5140 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141 return posix_error();
5142}
5143
Larry Hastings2f936352014-08-05 14:04:04 +10005144
5145/*[clinic input]
5146os.execve
5147
5148 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5149 Path of executable file.
5150 argv: object
5151 Tuple or list of strings.
5152 env: object
5153 Dictionary of strings mapping to strings.
5154
5155Execute an executable path with arguments, replacing current process.
5156[clinic start generated code]*/
5157
Larry Hastings2f936352014-08-05 14:04:04 +10005158static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005159os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5160/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005161{
Steve Dowercc16be82016-09-08 10:35:16 -07005162 EXECV_CHAR **argvlist = NULL;
5163 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005164 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005165
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 /* execve has three arguments: (path, argv, env), where
5167 argv is a list or tuple of strings and env is a dictionary
5168 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005169
Ross Lagerwall7807c352011-03-17 20:20:30 +02005170 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005172 "execve: argv must be a tuple or list");
5173 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005175 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005176 if (argc < 1) {
5177 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5178 return NULL;
5179 }
5180
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 if (!PyMapping_Check(env)) {
5182 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005183 "execve: environment must be a mapping object");
5184 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005186
Ross Lagerwall7807c352011-03-17 20:20:30 +02005187 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005189 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 }
Steve Dowerbce26262016-11-19 19:17:26 -08005191 if (!argvlist[0][0]) {
5192 PyErr_SetString(PyExc_ValueError,
5193 "execve: argv first element cannot be empty");
5194 goto fail;
5195 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005196
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 envlist = parse_envlist(env, &envc);
5198 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005199 goto fail;
5200
Steve Dowerbce26262016-11-19 19:17:26 -08005201 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005202#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005203 if (path->fd > -1)
5204 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005205 else
5206#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005207#ifdef HAVE_WEXECV
5208 _wexecve(path->wide, argvlist, envlist);
5209#else
Larry Hastings2f936352014-08-05 14:04:04 +10005210 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005211#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005212 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005213
5214 /* If we get here it's definitely an error */
5215
Alexey Izbyshev83460312018-10-20 03:28:22 +03005216 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005217
Steve Dowercc16be82016-09-08 10:35:16 -07005218 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005219 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005220 if (argvlist)
5221 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005222 return NULL;
5223}
Steve Dowercc16be82016-09-08 10:35:16 -07005224
Larry Hastings9cf065c2012-06-22 16:30:09 -07005225#endif /* HAVE_EXECV */
5226
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005227#ifdef HAVE_POSIX_SPAWN
5228
5229enum posix_spawn_file_actions_identifier {
5230 POSIX_SPAWN_OPEN,
5231 POSIX_SPAWN_CLOSE,
5232 POSIX_SPAWN_DUP2
5233};
5234
William Orr81574b82018-10-01 22:19:56 -07005235#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005236static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005237convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005238#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005239
5240static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005241parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5242 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005243 PyObject *setsigdef, PyObject *scheduler,
5244 posix_spawnattr_t *attrp)
5245{
5246 long all_flags = 0;
5247
5248 errno = posix_spawnattr_init(attrp);
5249 if (errno) {
5250 posix_error();
5251 return -1;
5252 }
5253
5254 if (setpgroup) {
5255 pid_t pgid = PyLong_AsPid(setpgroup);
5256 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5257 goto fail;
5258 }
5259 errno = posix_spawnattr_setpgroup(attrp, pgid);
5260 if (errno) {
5261 posix_error();
5262 goto fail;
5263 }
5264 all_flags |= POSIX_SPAWN_SETPGROUP;
5265 }
5266
5267 if (resetids) {
5268 all_flags |= POSIX_SPAWN_RESETIDS;
5269 }
5270
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005271 if (setsid) {
5272#ifdef POSIX_SPAWN_SETSID
5273 all_flags |= POSIX_SPAWN_SETSID;
5274#elif defined(POSIX_SPAWN_SETSID_NP)
5275 all_flags |= POSIX_SPAWN_SETSID_NP;
5276#else
5277 argument_unavailable_error(func_name, "setsid");
5278 return -1;
5279#endif
5280 }
5281
Pablo Galindo254a4662018-09-07 16:44:24 +01005282 if (setsigmask) {
5283 sigset_t set;
5284 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5285 goto fail;
5286 }
5287 errno = posix_spawnattr_setsigmask(attrp, &set);
5288 if (errno) {
5289 posix_error();
5290 goto fail;
5291 }
5292 all_flags |= POSIX_SPAWN_SETSIGMASK;
5293 }
5294
5295 if (setsigdef) {
5296 sigset_t set;
5297 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5298 goto fail;
5299 }
5300 errno = posix_spawnattr_setsigdefault(attrp, &set);
5301 if (errno) {
5302 posix_error();
5303 goto fail;
5304 }
5305 all_flags |= POSIX_SPAWN_SETSIGDEF;
5306 }
5307
5308 if (scheduler) {
5309#ifdef POSIX_SPAWN_SETSCHEDULER
5310 PyObject *py_schedpolicy;
5311 struct sched_param schedparam;
5312
5313 if (!PyArg_ParseTuple(scheduler, "OO&"
5314 ";A scheduler tuple must have two elements",
5315 &py_schedpolicy, convert_sched_param, &schedparam)) {
5316 goto fail;
5317 }
5318 if (py_schedpolicy != Py_None) {
5319 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5320
5321 if (schedpolicy == -1 && PyErr_Occurred()) {
5322 goto fail;
5323 }
5324 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5325 if (errno) {
5326 posix_error();
5327 goto fail;
5328 }
5329 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5330 }
5331 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5332 if (errno) {
5333 posix_error();
5334 goto fail;
5335 }
5336 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5337#else
5338 PyErr_SetString(PyExc_NotImplementedError,
5339 "The scheduler option is not supported in this system.");
5340 goto fail;
5341#endif
5342 }
5343
5344 errno = posix_spawnattr_setflags(attrp, all_flags);
5345 if (errno) {
5346 posix_error();
5347 goto fail;
5348 }
5349
5350 return 0;
5351
5352fail:
5353 (void)posix_spawnattr_destroy(attrp);
5354 return -1;
5355}
5356
5357static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005358parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005359 posix_spawn_file_actions_t *file_actionsp,
5360 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005361{
5362 PyObject *seq;
5363 PyObject *file_action = NULL;
5364 PyObject *tag_obj;
5365
5366 seq = PySequence_Fast(file_actions,
5367 "file_actions must be a sequence or None");
5368 if (seq == NULL) {
5369 return -1;
5370 }
5371
5372 errno = posix_spawn_file_actions_init(file_actionsp);
5373 if (errno) {
5374 posix_error();
5375 Py_DECREF(seq);
5376 return -1;
5377 }
5378
5379 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5380 file_action = PySequence_Fast_GET_ITEM(seq, i);
5381 Py_INCREF(file_action);
5382 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5383 PyErr_SetString(PyExc_TypeError,
5384 "Each file_actions element must be a non-empty tuple");
5385 goto fail;
5386 }
5387 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5388 if (tag == -1 && PyErr_Occurred()) {
5389 goto fail;
5390 }
5391
5392 /* Populate the file_actions object */
5393 switch (tag) {
5394 case POSIX_SPAWN_OPEN: {
5395 int fd, oflag;
5396 PyObject *path;
5397 unsigned long mode;
5398 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5399 ";A open file_action tuple must have 5 elements",
5400 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5401 &oflag, &mode))
5402 {
5403 goto fail;
5404 }
Pablo Galindocb970732018-06-19 09:19:50 +01005405 if (PyList_Append(temp_buffer, path)) {
5406 Py_DECREF(path);
5407 goto fail;
5408 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005409 errno = posix_spawn_file_actions_addopen(file_actionsp,
5410 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005411 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005412 if (errno) {
5413 posix_error();
5414 goto fail;
5415 }
5416 break;
5417 }
5418 case POSIX_SPAWN_CLOSE: {
5419 int fd;
5420 if (!PyArg_ParseTuple(file_action, "Oi"
5421 ";A close file_action tuple must have 2 elements",
5422 &tag_obj, &fd))
5423 {
5424 goto fail;
5425 }
5426 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5427 if (errno) {
5428 posix_error();
5429 goto fail;
5430 }
5431 break;
5432 }
5433 case POSIX_SPAWN_DUP2: {
5434 int fd1, fd2;
5435 if (!PyArg_ParseTuple(file_action, "Oii"
5436 ";A dup2 file_action tuple must have 3 elements",
5437 &tag_obj, &fd1, &fd2))
5438 {
5439 goto fail;
5440 }
5441 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5442 fd1, fd2);
5443 if (errno) {
5444 posix_error();
5445 goto fail;
5446 }
5447 break;
5448 }
5449 default: {
5450 PyErr_SetString(PyExc_TypeError,
5451 "Unknown file_actions identifier");
5452 goto fail;
5453 }
5454 }
5455 Py_DECREF(file_action);
5456 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005457
Serhiy Storchakaef347532018-05-01 16:45:04 +03005458 Py_DECREF(seq);
5459 return 0;
5460
5461fail:
5462 Py_DECREF(seq);
5463 Py_DECREF(file_action);
5464 (void)posix_spawn_file_actions_destroy(file_actionsp);
5465 return -1;
5466}
5467
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005468
5469static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005470py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5471 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005472 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005473 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005474{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005475 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005476 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005477 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005478 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005479 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005480 posix_spawnattr_t attr;
5481 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005482 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005483 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005484 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005485 pid_t pid;
5486 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005487
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005488 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005489 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005490 like posix.environ. */
5491
Serhiy Storchakaef347532018-05-01 16:45:04 +03005492 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005493 PyErr_Format(PyExc_TypeError,
5494 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005495 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005496 }
5497 argc = PySequence_Size(argv);
5498 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005499 PyErr_Format(PyExc_ValueError,
5500 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005501 return NULL;
5502 }
5503
5504 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005505 PyErr_Format(PyExc_TypeError,
5506 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005507 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005508 }
5509
5510 argvlist = parse_arglist(argv, &argc);
5511 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005512 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005513 }
5514 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005515 PyErr_Format(PyExc_ValueError,
5516 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005517 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005518 }
5519
5520 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005521 if (envlist == NULL) {
5522 goto exit;
5523 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005524
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005525 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005526 /* There is a bug in old versions of glibc that makes some of the
5527 * helper functions for manipulating file actions not copy the provided
5528 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5529 * copy the value of path for some old versions of glibc (<2.20).
5530 * The use of temp_buffer here is a workaround that keeps the
5531 * python objects that own the buffers alive until posix_spawn gets called.
5532 * Check https://bugs.python.org/issue33630 and
5533 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5534 temp_buffer = PyList_New(0);
5535 if (!temp_buffer) {
5536 goto exit;
5537 }
5538 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005539 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005540 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005541 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005542 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005543
Victor Stinner325e4ba2019-02-01 15:47:24 +01005544 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5545 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005546 goto exit;
5547 }
5548 attrp = &attr;
5549
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005550 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005551#ifdef HAVE_POSIX_SPAWNP
5552 if (use_posix_spawnp) {
5553 err_code = posix_spawnp(&pid, path->narrow,
5554 file_actionsp, attrp, argvlist, envlist);
5555 }
5556 else
5557#endif /* HAVE_POSIX_SPAWNP */
5558 {
5559 err_code = posix_spawn(&pid, path->narrow,
5560 file_actionsp, attrp, argvlist, envlist);
5561 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005562 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005563
Serhiy Storchakaef347532018-05-01 16:45:04 +03005564 if (err_code) {
5565 errno = err_code;
5566 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005567 goto exit;
5568 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005569#ifdef _Py_MEMORY_SANITIZER
5570 __msan_unpoison(&pid, sizeof(pid));
5571#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005572 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005573
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005574exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005575 if (file_actionsp) {
5576 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005577 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005578 if (attrp) {
5579 (void)posix_spawnattr_destroy(attrp);
5580 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005581 if (envlist) {
5582 free_string_array(envlist, envc);
5583 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005584 if (argvlist) {
5585 free_string_array(argvlist, argc);
5586 }
Pablo Galindocb970732018-06-19 09:19:50 +01005587 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005588 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005589}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005590
5591
5592/*[clinic input]
5593
5594os.posix_spawn
5595 path: path_t
5596 Path of executable file.
5597 argv: object
5598 Tuple or list of strings.
5599 env: object
5600 Dictionary of strings mapping to strings.
5601 /
5602 *
5603 file_actions: object(c_default='NULL') = ()
5604 A sequence of file action tuples.
5605 setpgroup: object = NULL
5606 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5607 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005608 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5609 setsid: bool(accept={int}) = False
5610 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005611 setsigmask: object(c_default='NULL') = ()
5612 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5613 setsigdef: object(c_default='NULL') = ()
5614 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5615 scheduler: object = NULL
5616 A tuple with the scheduler policy (optional) and parameters.
5617
5618Execute the program specified by path in a new process.
5619[clinic start generated code]*/
5620
5621static PyObject *
5622os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5623 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005624 PyObject *setpgroup, int resetids, int setsid,
5625 PyObject *setsigmask, PyObject *setsigdef,
5626 PyObject *scheduler)
5627/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005628{
5629 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005630 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005631 scheduler);
5632}
5633 #endif /* HAVE_POSIX_SPAWN */
5634
5635
5636
5637#ifdef HAVE_POSIX_SPAWNP
5638/*[clinic input]
5639
5640os.posix_spawnp
5641 path: path_t
5642 Path of executable file.
5643 argv: object
5644 Tuple or list of strings.
5645 env: object
5646 Dictionary of strings mapping to strings.
5647 /
5648 *
5649 file_actions: object(c_default='NULL') = ()
5650 A sequence of file action tuples.
5651 setpgroup: object = NULL
5652 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5653 resetids: bool(accept={int}) = False
5654 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005655 setsid: bool(accept={int}) = False
5656 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005657 setsigmask: object(c_default='NULL') = ()
5658 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5659 setsigdef: object(c_default='NULL') = ()
5660 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5661 scheduler: object = NULL
5662 A tuple with the scheduler policy (optional) and parameters.
5663
5664Execute the program specified by path in a new process.
5665[clinic start generated code]*/
5666
5667static PyObject *
5668os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5669 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005670 PyObject *setpgroup, int resetids, int setsid,
5671 PyObject *setsigmask, PyObject *setsigdef,
5672 PyObject *scheduler)
5673/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005674{
5675 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005676 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005677 scheduler);
5678}
5679#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005680
pxinwrf2d7ac72019-05-21 18:46:37 +08005681#ifdef HAVE_RTPSPAWN
5682static intptr_t
5683_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5684 const char *envp[])
5685{
5686 RTP_ID rtpid;
5687 int status;
5688 pid_t res;
5689 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005690
pxinwrf2d7ac72019-05-21 18:46:37 +08005691 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5692 uStackSize=0 cannot be used, the default stack size is too small for
5693 Python. */
5694 if (envp) {
5695 rtpid = rtpSpawn(rtpFileName, argv, envp,
5696 100, 0x1000000, 0, VX_FP_TASK);
5697 }
5698 else {
5699 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5700 100, 0x1000000, 0, VX_FP_TASK);
5701 }
5702 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5703 do {
5704 res = waitpid((pid_t)rtpid, &status, 0);
5705 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5706
5707 if (res < 0)
5708 return RTP_ID_ERROR;
5709 return ((intptr_t)status);
5710 }
5711 return ((intptr_t)rtpid);
5712}
5713#endif
5714
5715#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005716/*[clinic input]
5717os.spawnv
5718
5719 mode: int
5720 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005721 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005722 Path of executable file.
5723 argv: object
5724 Tuple or list of strings.
5725 /
5726
5727Execute the program specified by path in a new process.
5728[clinic start generated code]*/
5729
Larry Hastings2f936352014-08-05 14:04:04 +10005730static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005731os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5732/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005733{
Steve Dowercc16be82016-09-08 10:35:16 -07005734 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005735 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005737 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005738 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005739
Victor Stinner8c62be82010-05-06 00:08:46 +00005740 /* spawnv has three arguments: (mode, path, argv), where
5741 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005742
Victor Stinner8c62be82010-05-06 00:08:46 +00005743 if (PyList_Check(argv)) {
5744 argc = PyList_Size(argv);
5745 getitem = PyList_GetItem;
5746 }
5747 else if (PyTuple_Check(argv)) {
5748 argc = PyTuple_Size(argv);
5749 getitem = PyTuple_GetItem;
5750 }
5751 else {
5752 PyErr_SetString(PyExc_TypeError,
5753 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005754 return NULL;
5755 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005756 if (argc == 0) {
5757 PyErr_SetString(PyExc_ValueError,
5758 "spawnv() arg 2 cannot be empty");
5759 return NULL;
5760 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005761
Steve Dowercc16be82016-09-08 10:35:16 -07005762 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005763 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005764 return PyErr_NoMemory();
5765 }
5766 for (i = 0; i < argc; i++) {
5767 if (!fsconvert_strdup((*getitem)(argv, i),
5768 &argvlist[i])) {
5769 free_string_array(argvlist, i);
5770 PyErr_SetString(
5771 PyExc_TypeError,
5772 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005773 return NULL;
5774 }
Steve Dower93ff8722016-11-19 19:03:54 -08005775 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005776 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005777 PyErr_SetString(
5778 PyExc_ValueError,
5779 "spawnv() arg 2 first element cannot be empty");
5780 return NULL;
5781 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005782 }
5783 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005784
pxinwrf2d7ac72019-05-21 18:46:37 +08005785#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 if (mode == _OLD_P_OVERLAY)
5787 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005788#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005789
Victor Stinner8c62be82010-05-06 00:08:46 +00005790 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005791 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005792#ifdef HAVE_WSPAWNV
5793 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005794#elif defined(HAVE_RTPSPAWN)
5795 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005796#else
5797 spawnval = _spawnv(mode, path->narrow, argvlist);
5798#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005799 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005801
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005803
Victor Stinner8c62be82010-05-06 00:08:46 +00005804 if (spawnval == -1)
5805 return posix_error();
5806 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005807 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005808}
5809
Larry Hastings2f936352014-08-05 14:04:04 +10005810/*[clinic input]
5811os.spawnve
5812
5813 mode: int
5814 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005815 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005816 Path of executable file.
5817 argv: object
5818 Tuple or list of strings.
5819 env: object
5820 Dictionary of strings mapping to strings.
5821 /
5822
5823Execute the program specified by path in a new process.
5824[clinic start generated code]*/
5825
Larry Hastings2f936352014-08-05 14:04:04 +10005826static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005827os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005828 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005829/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005830{
Steve Dowercc16be82016-09-08 10:35:16 -07005831 EXECV_CHAR **argvlist;
5832 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005834 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005835 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005837 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005838
Victor Stinner8c62be82010-05-06 00:08:46 +00005839 /* spawnve has four arguments: (mode, path, argv, env), where
5840 argv is a list or tuple of strings and env is a dictionary
5841 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005842
Victor Stinner8c62be82010-05-06 00:08:46 +00005843 if (PyList_Check(argv)) {
5844 argc = PyList_Size(argv);
5845 getitem = PyList_GetItem;
5846 }
5847 else if (PyTuple_Check(argv)) {
5848 argc = PyTuple_Size(argv);
5849 getitem = PyTuple_GetItem;
5850 }
5851 else {
5852 PyErr_SetString(PyExc_TypeError,
5853 "spawnve() arg 2 must be a tuple or list");
5854 goto fail_0;
5855 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005856 if (argc == 0) {
5857 PyErr_SetString(PyExc_ValueError,
5858 "spawnve() arg 2 cannot be empty");
5859 goto fail_0;
5860 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005861 if (!PyMapping_Check(env)) {
5862 PyErr_SetString(PyExc_TypeError,
5863 "spawnve() arg 3 must be a mapping object");
5864 goto fail_0;
5865 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005866
Steve Dowercc16be82016-09-08 10:35:16 -07005867 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005868 if (argvlist == NULL) {
5869 PyErr_NoMemory();
5870 goto fail_0;
5871 }
5872 for (i = 0; i < argc; i++) {
5873 if (!fsconvert_strdup((*getitem)(argv, i),
5874 &argvlist[i]))
5875 {
5876 lastarg = i;
5877 goto fail_1;
5878 }
Steve Dowerbce26262016-11-19 19:17:26 -08005879 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005880 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005881 PyErr_SetString(
5882 PyExc_ValueError,
5883 "spawnv() arg 2 first element cannot be empty");
5884 goto fail_1;
5885 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 }
5887 lastarg = argc;
5888 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005889
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 envlist = parse_envlist(env, &envc);
5891 if (envlist == NULL)
5892 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005893
pxinwrf2d7ac72019-05-21 18:46:37 +08005894#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 if (mode == _OLD_P_OVERLAY)
5896 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005897#endif
Tim Peters25059d32001-12-07 20:35:43 +00005898
Victor Stinner8c62be82010-05-06 00:08:46 +00005899 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005900 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005901#ifdef HAVE_WSPAWNV
5902 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005903#elif defined(HAVE_RTPSPAWN)
5904 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
5905 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005906#else
5907 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5908#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005909 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005911
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 if (spawnval == -1)
5913 (void) posix_error();
5914 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005915 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005916
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 while (--envc >= 0)
5918 PyMem_DEL(envlist[envc]);
5919 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005920 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005921 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005922 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005924}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005925
Guido van Rossuma1065681999-01-25 23:20:23 +00005926#endif /* HAVE_SPAWNV */
5927
5928
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005929#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005930
5931/* Helper function to validate arguments.
5932 Returns 0 on success. non-zero on failure with a TypeError raised.
5933 If obj is non-NULL it must be callable. */
5934static int
5935check_null_or_callable(PyObject *obj, const char* obj_name)
5936{
5937 if (obj && !PyCallable_Check(obj)) {
5938 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5939 obj_name, Py_TYPE(obj)->tp_name);
5940 return -1;
5941 }
5942 return 0;
5943}
5944
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005945/*[clinic input]
5946os.register_at_fork
5947
Gregory P. Smith163468a2017-05-29 10:03:41 -07005948 *
5949 before: object=NULL
5950 A callable to be called in the parent before the fork() syscall.
5951 after_in_child: object=NULL
5952 A callable to be called in the child after fork().
5953 after_in_parent: object=NULL
5954 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005955
Gregory P. Smith163468a2017-05-29 10:03:41 -07005956Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005957
Gregory P. Smith163468a2017-05-29 10:03:41 -07005958'before' callbacks are called in reverse order.
5959'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005960
5961[clinic start generated code]*/
5962
5963static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005964os_register_at_fork_impl(PyObject *module, PyObject *before,
5965 PyObject *after_in_child, PyObject *after_in_parent)
5966/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005967{
5968 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005969
Gregory P. Smith163468a2017-05-29 10:03:41 -07005970 if (!before && !after_in_child && !after_in_parent) {
5971 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5972 return NULL;
5973 }
5974 if (check_null_or_callable(before, "before") ||
5975 check_null_or_callable(after_in_child, "after_in_child") ||
5976 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005977 return NULL;
5978 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005979 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005980
Gregory P. Smith163468a2017-05-29 10:03:41 -07005981 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005982 return NULL;
5983 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005984 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005985 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005986 }
5987 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5988 return NULL;
5989 }
5990 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005991}
5992#endif /* HAVE_FORK */
5993
5994
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005995#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005996/*[clinic input]
5997os.fork1
5998
5999Fork a child process with a single multiplexed (i.e., not bound) thread.
6000
6001Return 0 to child process and PID of child to parent process.
6002[clinic start generated code]*/
6003
Larry Hastings2f936352014-08-05 14:04:04 +10006004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006005os_fork1_impl(PyObject *module)
6006/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006007{
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006009
Eric Snow59032962018-09-14 14:17:20 -07006010 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6011 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6012 return NULL;
6013 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006014 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 pid = fork1();
6016 if (pid == 0) {
6017 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006018 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006019 } else {
6020 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006021 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006022 }
6023 if (pid == -1)
6024 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006026}
Larry Hastings2f936352014-08-05 14:04:04 +10006027#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006028
6029
Guido van Rossumad0ee831995-03-01 10:34:45 +00006030#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006031/*[clinic input]
6032os.fork
6033
6034Fork a child process.
6035
6036Return 0 to child process and PID of child to parent process.
6037[clinic start generated code]*/
6038
Larry Hastings2f936352014-08-05 14:04:04 +10006039static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006040os_fork_impl(PyObject *module)
6041/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006042{
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006044
Eric Snow59032962018-09-14 14:17:20 -07006045 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6046 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6047 return NULL;
6048 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006049 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006050 pid = fork();
6051 if (pid == 0) {
6052 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006053 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 } else {
6055 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006056 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 }
6058 if (pid == -1)
6059 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006061}
Larry Hastings2f936352014-08-05 14:04:04 +10006062#endif /* HAVE_FORK */
6063
Guido van Rossum85e3b011991-06-03 12:42:10 +00006064
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006065#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006066#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006067/*[clinic input]
6068os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006069
Larry Hastings2f936352014-08-05 14:04:04 +10006070 policy: int
6071
6072Get the maximum scheduling priority for policy.
6073[clinic start generated code]*/
6074
Larry Hastings2f936352014-08-05 14:04:04 +10006075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006076os_sched_get_priority_max_impl(PyObject *module, int policy)
6077/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006078{
6079 int max;
6080
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006081 max = sched_get_priority_max(policy);
6082 if (max < 0)
6083 return posix_error();
6084 return PyLong_FromLong(max);
6085}
6086
Larry Hastings2f936352014-08-05 14:04:04 +10006087
6088/*[clinic input]
6089os.sched_get_priority_min
6090
6091 policy: int
6092
6093Get the minimum scheduling priority for policy.
6094[clinic start generated code]*/
6095
Larry Hastings2f936352014-08-05 14:04:04 +10006096static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006097os_sched_get_priority_min_impl(PyObject *module, int policy)
6098/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006099{
6100 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006101 if (min < 0)
6102 return posix_error();
6103 return PyLong_FromLong(min);
6104}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006105#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6106
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006107
Larry Hastings2f936352014-08-05 14:04:04 +10006108#ifdef HAVE_SCHED_SETSCHEDULER
6109/*[clinic input]
6110os.sched_getscheduler
6111 pid: pid_t
6112 /
6113
6114Get the scheduling policy for the process identifiedy by pid.
6115
6116Passing 0 for pid returns the scheduling policy for the calling process.
6117[clinic start generated code]*/
6118
Larry Hastings2f936352014-08-05 14:04:04 +10006119static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006120os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6121/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006122{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006123 int policy;
6124
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006125 policy = sched_getscheduler(pid);
6126 if (policy < 0)
6127 return posix_error();
6128 return PyLong_FromLong(policy);
6129}
Larry Hastings2f936352014-08-05 14:04:04 +10006130#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006131
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006132
William Orr81574b82018-10-01 22:19:56 -07006133#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006134/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006135class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006136
6137@classmethod
6138os.sched_param.__new__
6139
6140 sched_priority: object
6141 A scheduling parameter.
6142
6143Current has only one field: sched_priority");
6144[clinic start generated code]*/
6145
Larry Hastings2f936352014-08-05 14:04:04 +10006146static PyObject *
6147os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006148/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006149{
6150 PyObject *res;
6151
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006152 res = PyStructSequence_New(type);
6153 if (!res)
6154 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006155 Py_INCREF(sched_priority);
6156 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006157 return res;
6158}
6159
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006160
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006161PyDoc_VAR(os_sched_param__doc__);
6162
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006163static PyStructSequence_Field sched_param_fields[] = {
6164 {"sched_priority", "the scheduling priority"},
6165 {0}
6166};
6167
6168static PyStructSequence_Desc sched_param_desc = {
6169 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006170 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006171 sched_param_fields,
6172 1
6173};
6174
6175static int
6176convert_sched_param(PyObject *param, struct sched_param *res)
6177{
6178 long priority;
6179
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006180 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006181 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6182 return 0;
6183 }
6184 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6185 if (priority == -1 && PyErr_Occurred())
6186 return 0;
6187 if (priority > INT_MAX || priority < INT_MIN) {
6188 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6189 return 0;
6190 }
6191 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6192 return 1;
6193}
William Orr81574b82018-10-01 22:19:56 -07006194#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006195
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006196
6197#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006198/*[clinic input]
6199os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006200
Larry Hastings2f936352014-08-05 14:04:04 +10006201 pid: pid_t
6202 policy: int
6203 param: sched_param
6204 /
6205
6206Set the scheduling policy for the process identified by pid.
6207
6208If pid is 0, the calling process is changed.
6209param is an instance of sched_param.
6210[clinic start generated code]*/
6211
Larry Hastings2f936352014-08-05 14:04:04 +10006212static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006213os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006214 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006215/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006216{
Jesus Cea9c822272011-09-10 01:40:52 +02006217 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006218 ** sched_setscheduler() returns 0 in Linux, but the previous
6219 ** scheduling policy under Solaris/Illumos, and others.
6220 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006221 */
Larry Hastings2f936352014-08-05 14:04:04 +10006222 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006223 return posix_error();
6224 Py_RETURN_NONE;
6225}
Larry Hastings2f936352014-08-05 14:04:04 +10006226#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006227
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006228
6229#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006230/*[clinic input]
6231os.sched_getparam
6232 pid: pid_t
6233 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006234
Larry Hastings2f936352014-08-05 14:04:04 +10006235Returns scheduling parameters for the process identified by pid.
6236
6237If pid is 0, returns parameters for the calling process.
6238Return value is an instance of sched_param.
6239[clinic start generated code]*/
6240
Larry Hastings2f936352014-08-05 14:04:04 +10006241static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006242os_sched_getparam_impl(PyObject *module, pid_t pid)
6243/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006244{
6245 struct sched_param param;
6246 PyObject *result;
6247 PyObject *priority;
6248
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006249 if (sched_getparam(pid, &param))
6250 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006251 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006252 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006253 return NULL;
6254 priority = PyLong_FromLong(param.sched_priority);
6255 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006256 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006257 return NULL;
6258 }
Larry Hastings2f936352014-08-05 14:04:04 +10006259 PyStructSequence_SET_ITEM(result, 0, priority);
6260 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006261}
6262
Larry Hastings2f936352014-08-05 14:04:04 +10006263
6264/*[clinic input]
6265os.sched_setparam
6266 pid: pid_t
6267 param: sched_param
6268 /
6269
6270Set scheduling parameters for the process identified by pid.
6271
6272If pid is 0, sets parameters for the calling process.
6273param should be an instance of sched_param.
6274[clinic start generated code]*/
6275
Larry Hastings2f936352014-08-05 14:04:04 +10006276static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006277os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006278 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006279/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006280{
6281 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006282 return posix_error();
6283 Py_RETURN_NONE;
6284}
Larry Hastings2f936352014-08-05 14:04:04 +10006285#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006286
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006287
6288#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006289/*[clinic input]
6290os.sched_rr_get_interval -> double
6291 pid: pid_t
6292 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006293
Larry Hastings2f936352014-08-05 14:04:04 +10006294Return the round-robin quantum for the process identified by pid, in seconds.
6295
6296Value returned is a float.
6297[clinic start generated code]*/
6298
Larry Hastings2f936352014-08-05 14:04:04 +10006299static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006300os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6301/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006302{
6303 struct timespec interval;
6304 if (sched_rr_get_interval(pid, &interval)) {
6305 posix_error();
6306 return -1.0;
6307 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006308#ifdef _Py_MEMORY_SANITIZER
6309 __msan_unpoison(&interval, sizeof(interval));
6310#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006311 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6312}
6313#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006314
Larry Hastings2f936352014-08-05 14:04:04 +10006315
6316/*[clinic input]
6317os.sched_yield
6318
6319Voluntarily relinquish the CPU.
6320[clinic start generated code]*/
6321
Larry Hastings2f936352014-08-05 14:04:04 +10006322static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006323os_sched_yield_impl(PyObject *module)
6324/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006325{
6326 if (sched_yield())
6327 return posix_error();
6328 Py_RETURN_NONE;
6329}
6330
Benjamin Peterson2740af82011-08-02 17:41:34 -05006331#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006332/* The minimum number of CPUs allocated in a cpu_set_t */
6333static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006334
Larry Hastings2f936352014-08-05 14:04:04 +10006335/*[clinic input]
6336os.sched_setaffinity
6337 pid: pid_t
6338 mask : object
6339 /
6340
6341Set the CPU affinity of the process identified by pid to mask.
6342
6343mask should be an iterable of integers identifying CPUs.
6344[clinic start generated code]*/
6345
Larry Hastings2f936352014-08-05 14:04:04 +10006346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006347os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6348/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006349{
Antoine Pitrou84869872012-08-04 16:16:35 +02006350 int ncpus;
6351 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006352 cpu_set_t *cpu_set = NULL;
6353 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006354
Larry Hastings2f936352014-08-05 14:04:04 +10006355 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006356 if (iterator == NULL)
6357 return NULL;
6358
6359 ncpus = NCPUS_START;
6360 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006361 cpu_set = CPU_ALLOC(ncpus);
6362 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006363 PyErr_NoMemory();
6364 goto error;
6365 }
Larry Hastings2f936352014-08-05 14:04:04 +10006366 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006367
6368 while ((item = PyIter_Next(iterator))) {
6369 long cpu;
6370 if (!PyLong_Check(item)) {
6371 PyErr_Format(PyExc_TypeError,
6372 "expected an iterator of ints, "
6373 "but iterator yielded %R",
6374 Py_TYPE(item));
6375 Py_DECREF(item);
6376 goto error;
6377 }
6378 cpu = PyLong_AsLong(item);
6379 Py_DECREF(item);
6380 if (cpu < 0) {
6381 if (!PyErr_Occurred())
6382 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6383 goto error;
6384 }
6385 if (cpu > INT_MAX - 1) {
6386 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6387 goto error;
6388 }
6389 if (cpu >= ncpus) {
6390 /* Grow CPU mask to fit the CPU number */
6391 int newncpus = ncpus;
6392 cpu_set_t *newmask;
6393 size_t newsetsize;
6394 while (newncpus <= cpu) {
6395 if (newncpus > INT_MAX / 2)
6396 newncpus = cpu + 1;
6397 else
6398 newncpus = newncpus * 2;
6399 }
6400 newmask = CPU_ALLOC(newncpus);
6401 if (newmask == NULL) {
6402 PyErr_NoMemory();
6403 goto error;
6404 }
6405 newsetsize = CPU_ALLOC_SIZE(newncpus);
6406 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006407 memcpy(newmask, cpu_set, setsize);
6408 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006409 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006410 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006411 ncpus = newncpus;
6412 }
Larry Hastings2f936352014-08-05 14:04:04 +10006413 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006414 }
6415 Py_CLEAR(iterator);
6416
Larry Hastings2f936352014-08-05 14:04:04 +10006417 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006418 posix_error();
6419 goto error;
6420 }
Larry Hastings2f936352014-08-05 14:04:04 +10006421 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006422 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006423
6424error:
Larry Hastings2f936352014-08-05 14:04:04 +10006425 if (cpu_set)
6426 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006427 Py_XDECREF(iterator);
6428 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006429}
6430
Larry Hastings2f936352014-08-05 14:04:04 +10006431
6432/*[clinic input]
6433os.sched_getaffinity
6434 pid: pid_t
6435 /
6436
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006437Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006438
6439The affinity is returned as a set of CPU identifiers.
6440[clinic start generated code]*/
6441
Larry Hastings2f936352014-08-05 14:04:04 +10006442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006443os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006444/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006445{
Antoine Pitrou84869872012-08-04 16:16:35 +02006446 int cpu, ncpus, count;
6447 size_t setsize;
6448 cpu_set_t *mask = NULL;
6449 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006450
Antoine Pitrou84869872012-08-04 16:16:35 +02006451 ncpus = NCPUS_START;
6452 while (1) {
6453 setsize = CPU_ALLOC_SIZE(ncpus);
6454 mask = CPU_ALLOC(ncpus);
6455 if (mask == NULL)
6456 return PyErr_NoMemory();
6457 if (sched_getaffinity(pid, setsize, mask) == 0)
6458 break;
6459 CPU_FREE(mask);
6460 if (errno != EINVAL)
6461 return posix_error();
6462 if (ncpus > INT_MAX / 2) {
6463 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6464 "a large enough CPU set");
6465 return NULL;
6466 }
6467 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006468 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006469
6470 res = PySet_New(NULL);
6471 if (res == NULL)
6472 goto error;
6473 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6474 if (CPU_ISSET_S(cpu, setsize, mask)) {
6475 PyObject *cpu_num = PyLong_FromLong(cpu);
6476 --count;
6477 if (cpu_num == NULL)
6478 goto error;
6479 if (PySet_Add(res, cpu_num)) {
6480 Py_DECREF(cpu_num);
6481 goto error;
6482 }
6483 Py_DECREF(cpu_num);
6484 }
6485 }
6486 CPU_FREE(mask);
6487 return res;
6488
6489error:
6490 if (mask)
6491 CPU_FREE(mask);
6492 Py_XDECREF(res);
6493 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006494}
6495
Benjamin Peterson2740af82011-08-02 17:41:34 -05006496#endif /* HAVE_SCHED_SETAFFINITY */
6497
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006498#endif /* HAVE_SCHED_H */
6499
Larry Hastings2f936352014-08-05 14:04:04 +10006500
Neal Norwitzb59798b2003-03-21 01:43:31 +00006501/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006502/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6503#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006504#define DEV_PTY_FILE "/dev/ptc"
6505#define HAVE_DEV_PTMX
6506#else
6507#define DEV_PTY_FILE "/dev/ptmx"
6508#endif
6509
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006510#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006511#ifdef HAVE_PTY_H
6512#include <pty.h>
6513#else
6514#ifdef HAVE_LIBUTIL_H
6515#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006516#else
6517#ifdef HAVE_UTIL_H
6518#include <util.h>
6519#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006520#endif /* HAVE_LIBUTIL_H */
6521#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006522#ifdef HAVE_STROPTS_H
6523#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006524#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006525#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006526
Larry Hastings2f936352014-08-05 14:04:04 +10006527
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006528#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006529/*[clinic input]
6530os.openpty
6531
6532Open a pseudo-terminal.
6533
6534Return a tuple of (master_fd, slave_fd) containing open file descriptors
6535for both the master and slave ends.
6536[clinic start generated code]*/
6537
Larry Hastings2f936352014-08-05 14:04:04 +10006538static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006539os_openpty_impl(PyObject *module)
6540/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006541{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006542 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006543#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006545#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006546#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006548#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006550#endif
6551#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006552
Thomas Wouters70c21a12000-07-14 14:28:33 +00006553#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006555 goto posix_error;
6556
6557 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6558 goto error;
6559 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6560 goto error;
6561
Neal Norwitzb59798b2003-03-21 01:43:31 +00006562#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6564 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006565 goto posix_error;
6566 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6567 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006568
Victor Stinnerdaf45552013-08-28 00:53:59 +02006569 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006571 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006572
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006573#else
Victor Stinner000de532013-11-25 23:19:58 +01006574 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006576 goto posix_error;
6577
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006579
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 /* change permission of slave */
6581 if (grantpt(master_fd) < 0) {
6582 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006583 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006585
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 /* unlock slave */
6587 if (unlockpt(master_fd) < 0) {
6588 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006589 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006591
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006593
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 slave_name = ptsname(master_fd); /* get name of slave */
6595 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006596 goto posix_error;
6597
6598 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006599 if (slave_fd == -1)
6600 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006601
6602 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6603 goto posix_error;
6604
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006605#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006606 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6607 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006608#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006609 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006610#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006611#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006612#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006613
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006615
Victor Stinnerdaf45552013-08-28 00:53:59 +02006616posix_error:
6617 posix_error();
6618error:
6619 if (master_fd != -1)
6620 close(master_fd);
6621 if (slave_fd != -1)
6622 close(slave_fd);
6623 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006624}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006625#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006626
Larry Hastings2f936352014-08-05 14:04:04 +10006627
Fred Drake8cef4cf2000-06-28 16:40:38 +00006628#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006629/*[clinic input]
6630os.forkpty
6631
6632Fork a new process with a new pseudo-terminal as controlling tty.
6633
6634Returns a tuple of (pid, master_fd).
6635Like fork(), return pid of 0 to the child process,
6636and pid of child to the parent process.
6637To both, return fd of newly opened pseudo-terminal.
6638[clinic start generated code]*/
6639
Larry Hastings2f936352014-08-05 14:04:04 +10006640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006641os_forkpty_impl(PyObject *module)
6642/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006643{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006644 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006645 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006646
Eric Snow59032962018-09-14 14:17:20 -07006647 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6648 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6649 return NULL;
6650 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006651 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 pid = forkpty(&master_fd, NULL, NULL, NULL);
6653 if (pid == 0) {
6654 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006655 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 } else {
6657 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006658 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 }
6660 if (pid == -1)
6661 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006663}
Larry Hastings2f936352014-08-05 14:04:04 +10006664#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006665
Ross Lagerwall7807c352011-03-17 20:20:30 +02006666
Guido van Rossumad0ee831995-03-01 10:34:45 +00006667#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006668/*[clinic input]
6669os.getegid
6670
6671Return the current process's effective group id.
6672[clinic start generated code]*/
6673
Larry Hastings2f936352014-08-05 14:04:04 +10006674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006675os_getegid_impl(PyObject *module)
6676/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006677{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006678 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006679}
Larry Hastings2f936352014-08-05 14:04:04 +10006680#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006681
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006682
Guido van Rossumad0ee831995-03-01 10:34:45 +00006683#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006684/*[clinic input]
6685os.geteuid
6686
6687Return the current process's effective user id.
6688[clinic start generated code]*/
6689
Larry Hastings2f936352014-08-05 14:04:04 +10006690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006691os_geteuid_impl(PyObject *module)
6692/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006693{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006694 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006695}
Larry Hastings2f936352014-08-05 14:04:04 +10006696#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006698
Guido van Rossumad0ee831995-03-01 10:34:45 +00006699#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006700/*[clinic input]
6701os.getgid
6702
6703Return the current process's group id.
6704[clinic start generated code]*/
6705
Larry Hastings2f936352014-08-05 14:04:04 +10006706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006707os_getgid_impl(PyObject *module)
6708/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006709{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006710 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006711}
Larry Hastings2f936352014-08-05 14:04:04 +10006712#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006714
Berker Peksag39404992016-09-15 20:45:16 +03006715#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006716/*[clinic input]
6717os.getpid
6718
6719Return the current process id.
6720[clinic start generated code]*/
6721
Larry Hastings2f936352014-08-05 14:04:04 +10006722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006723os_getpid_impl(PyObject *module)
6724/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006725{
Victor Stinner8c62be82010-05-06 00:08:46 +00006726 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006727}
Berker Peksag39404992016-09-15 20:45:16 +03006728#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006729
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006730#ifdef NGROUPS_MAX
6731#define MAX_GROUPS NGROUPS_MAX
6732#else
6733 /* defined to be 16 on Solaris7, so this should be a small number */
6734#define MAX_GROUPS 64
6735#endif
6736
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006737#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006738
6739/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006740PyDoc_STRVAR(posix_getgrouplist__doc__,
6741"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6742Returns a list of groups to which a user belongs.\n\n\
6743 user: username to lookup\n\
6744 group: base group id of the user");
6745
6746static PyObject *
6747posix_getgrouplist(PyObject *self, PyObject *args)
6748{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006749 const char *user;
6750 int i, ngroups;
6751 PyObject *list;
6752#ifdef __APPLE__
6753 int *groups, basegid;
6754#else
6755 gid_t *groups, basegid;
6756#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006757
6758 /*
6759 * NGROUPS_MAX is defined by POSIX.1 as the maximum
6760 * number of supplimental groups a users can belong to.
6761 * We have to increment it by one because
6762 * getgrouplist() returns both the supplemental groups
6763 * and the primary group, i.e. all of the groups the
6764 * user belongs to.
6765 */
6766 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006767
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006768#ifdef __APPLE__
6769 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006770 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006771#else
6772 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6773 _Py_Gid_Converter, &basegid))
6774 return NULL;
6775#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006776
6777#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006778 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006779#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006780 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006781#endif
6782 if (groups == NULL)
6783 return PyErr_NoMemory();
6784
6785 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6786 PyMem_Del(groups);
6787 return posix_error();
6788 }
6789
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006790#ifdef _Py_MEMORY_SANITIZER
6791 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6792 __msan_unpoison(&ngroups, sizeof(ngroups));
6793 __msan_unpoison(groups, ngroups*sizeof(*groups));
6794#endif
6795
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006796 list = PyList_New(ngroups);
6797 if (list == NULL) {
6798 PyMem_Del(groups);
6799 return NULL;
6800 }
6801
6802 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006803#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006804 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006805#else
6806 PyObject *o = _PyLong_FromGid(groups[i]);
6807#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006808 if (o == NULL) {
6809 Py_DECREF(list);
6810 PyMem_Del(groups);
6811 return NULL;
6812 }
6813 PyList_SET_ITEM(list, i, o);
6814 }
6815
6816 PyMem_Del(groups);
6817
6818 return list;
6819}
Larry Hastings2f936352014-08-05 14:04:04 +10006820#endif /* HAVE_GETGROUPLIST */
6821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006822
Fred Drakec9680921999-12-13 16:37:25 +00006823#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006824/*[clinic input]
6825os.getgroups
6826
6827Return list of supplemental group IDs for the process.
6828[clinic start generated code]*/
6829
Larry Hastings2f936352014-08-05 14:04:04 +10006830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006831os_getgroups_impl(PyObject *module)
6832/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006833{
6834 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006836
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006837 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006838 * This is a helper variable to store the intermediate result when
6839 * that happens.
6840 *
6841 * To keep the code readable the OSX behaviour is unconditional,
6842 * according to the POSIX spec this should be safe on all unix-y
6843 * systems.
6844 */
6845 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006847
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006848#ifdef __APPLE__
6849 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6850 * there are more groups than can fit in grouplist. Therefore, on OS X
6851 * always first call getgroups with length 0 to get the actual number
6852 * of groups.
6853 */
6854 n = getgroups(0, NULL);
6855 if (n < 0) {
6856 return posix_error();
6857 } else if (n <= MAX_GROUPS) {
6858 /* groups will fit in existing array */
6859 alt_grouplist = grouplist;
6860 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006861 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006862 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006863 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006864 }
6865 }
6866
6867 n = getgroups(n, alt_grouplist);
6868 if (n == -1) {
6869 if (alt_grouplist != grouplist) {
6870 PyMem_Free(alt_grouplist);
6871 }
6872 return posix_error();
6873 }
6874#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006876 if (n < 0) {
6877 if (errno == EINVAL) {
6878 n = getgroups(0, NULL);
6879 if (n == -1) {
6880 return posix_error();
6881 }
6882 if (n == 0) {
6883 /* Avoid malloc(0) */
6884 alt_grouplist = grouplist;
6885 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006886 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006887 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006888 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006889 }
6890 n = getgroups(n, alt_grouplist);
6891 if (n == -1) {
6892 PyMem_Free(alt_grouplist);
6893 return posix_error();
6894 }
6895 }
6896 } else {
6897 return posix_error();
6898 }
6899 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006900#endif
6901
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006902 result = PyList_New(n);
6903 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 int i;
6905 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006906 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006908 Py_DECREF(result);
6909 result = NULL;
6910 break;
Fred Drakec9680921999-12-13 16:37:25 +00006911 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006913 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006914 }
6915
6916 if (alt_grouplist != grouplist) {
6917 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006919
Fred Drakec9680921999-12-13 16:37:25 +00006920 return result;
6921}
Larry Hastings2f936352014-08-05 14:04:04 +10006922#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006923
Antoine Pitroub7572f02009-12-02 20:46:48 +00006924#ifdef HAVE_INITGROUPS
6925PyDoc_STRVAR(posix_initgroups__doc__,
6926"initgroups(username, gid) -> None\n\n\
6927Call the system initgroups() to initialize the group access list with all of\n\
6928the groups of which the specified username is a member, plus the specified\n\
6929group id.");
6930
Larry Hastings2f936352014-08-05 14:04:04 +10006931/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006932static PyObject *
6933posix_initgroups(PyObject *self, PyObject *args)
6934{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006935 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006936 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006937 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006938#ifdef __APPLE__
6939 int gid;
6940#else
6941 gid_t gid;
6942#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006943
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006944#ifdef __APPLE__
6945 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6946 PyUnicode_FSConverter, &oname,
6947 &gid))
6948#else
6949 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6950 PyUnicode_FSConverter, &oname,
6951 _Py_Gid_Converter, &gid))
6952#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006954 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006955
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006956 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006957 Py_DECREF(oname);
6958 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006960
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006961 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006962}
Larry Hastings2f936352014-08-05 14:04:04 +10006963#endif /* HAVE_INITGROUPS */
6964
Antoine Pitroub7572f02009-12-02 20:46:48 +00006965
Martin v. Löwis606edc12002-06-13 21:09:11 +00006966#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006967/*[clinic input]
6968os.getpgid
6969
6970 pid: pid_t
6971
6972Call the system call getpgid(), and return the result.
6973[clinic start generated code]*/
6974
Larry Hastings2f936352014-08-05 14:04:04 +10006975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006976os_getpgid_impl(PyObject *module, pid_t pid)
6977/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006978{
6979 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 if (pgid < 0)
6981 return posix_error();
6982 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006983}
6984#endif /* HAVE_GETPGID */
6985
6986
Guido van Rossumb6775db1994-08-01 11:34:53 +00006987#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006988/*[clinic input]
6989os.getpgrp
6990
6991Return the current process group id.
6992[clinic start generated code]*/
6993
Larry Hastings2f936352014-08-05 14:04:04 +10006994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006995os_getpgrp_impl(PyObject *module)
6996/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006997{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006998#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007000#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007002#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007003}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007004#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007006
Guido van Rossumb6775db1994-08-01 11:34:53 +00007007#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007008/*[clinic input]
7009os.setpgrp
7010
7011Make the current process the leader of its process group.
7012[clinic start generated code]*/
7013
Larry Hastings2f936352014-08-05 14:04:04 +10007014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007015os_setpgrp_impl(PyObject *module)
7016/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007017{
Guido van Rossum64933891994-10-20 21:56:42 +00007018#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007020#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007022#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007023 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007024 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007025}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007026#endif /* HAVE_SETPGRP */
7027
Guido van Rossumad0ee831995-03-01 10:34:45 +00007028#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007029
7030#ifdef MS_WINDOWS
7031#include <tlhelp32.h>
7032
7033static PyObject*
7034win32_getppid()
7035{
7036 HANDLE snapshot;
7037 pid_t mypid;
7038 PyObject* result = NULL;
7039 BOOL have_record;
7040 PROCESSENTRY32 pe;
7041
7042 mypid = getpid(); /* This function never fails */
7043
7044 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7045 if (snapshot == INVALID_HANDLE_VALUE)
7046 return PyErr_SetFromWindowsErr(GetLastError());
7047
7048 pe.dwSize = sizeof(pe);
7049 have_record = Process32First(snapshot, &pe);
7050 while (have_record) {
7051 if (mypid == (pid_t)pe.th32ProcessID) {
7052 /* We could cache the ulong value in a static variable. */
7053 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7054 break;
7055 }
7056
7057 have_record = Process32Next(snapshot, &pe);
7058 }
7059
7060 /* If our loop exits and our pid was not found (result will be NULL)
7061 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7062 * error anyway, so let's raise it. */
7063 if (!result)
7064 result = PyErr_SetFromWindowsErr(GetLastError());
7065
7066 CloseHandle(snapshot);
7067
7068 return result;
7069}
7070#endif /*MS_WINDOWS*/
7071
Larry Hastings2f936352014-08-05 14:04:04 +10007072
7073/*[clinic input]
7074os.getppid
7075
7076Return the parent's process id.
7077
7078If the parent process has already exited, Windows machines will still
7079return its id; others systems will return the id of the 'init' process (1).
7080[clinic start generated code]*/
7081
Larry Hastings2f936352014-08-05 14:04:04 +10007082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007083os_getppid_impl(PyObject *module)
7084/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007085{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007086#ifdef MS_WINDOWS
7087 return win32_getppid();
7088#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007089 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007090#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007091}
7092#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007093
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007094
Fred Drake12c6e2d1999-12-14 21:25:03 +00007095#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007096/*[clinic input]
7097os.getlogin
7098
7099Return the actual login name.
7100[clinic start generated code]*/
7101
Larry Hastings2f936352014-08-05 14:04:04 +10007102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007103os_getlogin_impl(PyObject *module)
7104/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007105{
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007107#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007108 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007109 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007110
7111 if (GetUserNameW(user_name, &num_chars)) {
7112 /* num_chars is the number of unicode chars plus null terminator */
7113 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007114 }
7115 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007116 result = PyErr_SetFromWindowsErr(GetLastError());
7117#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 char *name;
7119 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007120
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 errno = 0;
7122 name = getlogin();
7123 if (name == NULL) {
7124 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007125 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007126 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007127 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 }
7129 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007130 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007131 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007132#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007133 return result;
7134}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007135#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007136
Larry Hastings2f936352014-08-05 14:04:04 +10007137
Guido van Rossumad0ee831995-03-01 10:34:45 +00007138#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007139/*[clinic input]
7140os.getuid
7141
7142Return the current process's user id.
7143[clinic start generated code]*/
7144
Larry Hastings2f936352014-08-05 14:04:04 +10007145static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007146os_getuid_impl(PyObject *module)
7147/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007148{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007149 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007150}
Larry Hastings2f936352014-08-05 14:04:04 +10007151#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007153
Brian Curtineb24d742010-04-12 17:16:38 +00007154#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007155#define HAVE_KILL
7156#endif /* MS_WINDOWS */
7157
7158#ifdef HAVE_KILL
7159/*[clinic input]
7160os.kill
7161
7162 pid: pid_t
7163 signal: Py_ssize_t
7164 /
7165
7166Kill a process with a signal.
7167[clinic start generated code]*/
7168
Larry Hastings2f936352014-08-05 14:04:04 +10007169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007170os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7171/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007172#ifndef MS_WINDOWS
7173{
7174 if (kill(pid, (int)signal) == -1)
7175 return posix_error();
7176 Py_RETURN_NONE;
7177}
7178#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007179{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007180 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007181 DWORD sig = (DWORD)signal;
7182 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007184
Victor Stinner8c62be82010-05-06 00:08:46 +00007185 /* Console processes which share a common console can be sent CTRL+C or
7186 CTRL+BREAK events, provided they handle said events. */
7187 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007188 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 err = GetLastError();
7190 PyErr_SetFromWindowsErr(err);
7191 }
7192 else
7193 Py_RETURN_NONE;
7194 }
Brian Curtineb24d742010-04-12 17:16:38 +00007195
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7197 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007198 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 if (handle == NULL) {
7200 err = GetLastError();
7201 return PyErr_SetFromWindowsErr(err);
7202 }
Brian Curtineb24d742010-04-12 17:16:38 +00007203
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 if (TerminateProcess(handle, sig) == 0) {
7205 err = GetLastError();
7206 result = PyErr_SetFromWindowsErr(err);
7207 } else {
7208 Py_INCREF(Py_None);
7209 result = Py_None;
7210 }
Brian Curtineb24d742010-04-12 17:16:38 +00007211
Victor Stinner8c62be82010-05-06 00:08:46 +00007212 CloseHandle(handle);
7213 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007214}
Larry Hastings2f936352014-08-05 14:04:04 +10007215#endif /* !MS_WINDOWS */
7216#endif /* HAVE_KILL */
7217
7218
7219#ifdef HAVE_KILLPG
7220/*[clinic input]
7221os.killpg
7222
7223 pgid: pid_t
7224 signal: int
7225 /
7226
7227Kill a process group with a signal.
7228[clinic start generated code]*/
7229
Larry Hastings2f936352014-08-05 14:04:04 +10007230static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007231os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7232/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007233{
7234 /* XXX some man pages make the `pgid` parameter an int, others
7235 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7236 take the same type. Moreover, pid_t is always at least as wide as
7237 int (else compilation of this module fails), which is safe. */
7238 if (killpg(pgid, signal) == -1)
7239 return posix_error();
7240 Py_RETURN_NONE;
7241}
7242#endif /* HAVE_KILLPG */
7243
Brian Curtineb24d742010-04-12 17:16:38 +00007244
Guido van Rossumc0125471996-06-28 18:55:32 +00007245#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007246#ifdef HAVE_SYS_LOCK_H
7247#include <sys/lock.h>
7248#endif
7249
Larry Hastings2f936352014-08-05 14:04:04 +10007250/*[clinic input]
7251os.plock
7252 op: int
7253 /
7254
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007255Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007256[clinic start generated code]*/
7257
Larry Hastings2f936352014-08-05 14:04:04 +10007258static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007259os_plock_impl(PyObject *module, int op)
7260/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007261{
Victor Stinner8c62be82010-05-06 00:08:46 +00007262 if (plock(op) == -1)
7263 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007264 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007265}
Larry Hastings2f936352014-08-05 14:04:04 +10007266#endif /* HAVE_PLOCK */
7267
Guido van Rossumc0125471996-06-28 18:55:32 +00007268
Guido van Rossumb6775db1994-08-01 11:34:53 +00007269#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007270/*[clinic input]
7271os.setuid
7272
7273 uid: uid_t
7274 /
7275
7276Set the current process's user id.
7277[clinic start generated code]*/
7278
Larry Hastings2f936352014-08-05 14:04:04 +10007279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007280os_setuid_impl(PyObject *module, uid_t uid)
7281/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007282{
Victor Stinner8c62be82010-05-06 00:08:46 +00007283 if (setuid(uid) < 0)
7284 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007285 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007286}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007287#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007289
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007290#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007291/*[clinic input]
7292os.seteuid
7293
7294 euid: uid_t
7295 /
7296
7297Set the current process's effective user id.
7298[clinic start generated code]*/
7299
Larry Hastings2f936352014-08-05 14:04:04 +10007300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007301os_seteuid_impl(PyObject *module, uid_t euid)
7302/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007303{
7304 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007305 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007306 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007307}
7308#endif /* HAVE_SETEUID */
7309
Larry Hastings2f936352014-08-05 14:04:04 +10007310
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007311#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007312/*[clinic input]
7313os.setegid
7314
7315 egid: gid_t
7316 /
7317
7318Set the current process's effective group id.
7319[clinic start generated code]*/
7320
Larry Hastings2f936352014-08-05 14:04:04 +10007321static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007322os_setegid_impl(PyObject *module, gid_t egid)
7323/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007324{
7325 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007326 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007327 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007328}
7329#endif /* HAVE_SETEGID */
7330
Larry Hastings2f936352014-08-05 14:04:04 +10007331
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007332#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007333/*[clinic input]
7334os.setreuid
7335
7336 ruid: uid_t
7337 euid: uid_t
7338 /
7339
7340Set the current process's real and effective user ids.
7341[clinic start generated code]*/
7342
Larry Hastings2f936352014-08-05 14:04:04 +10007343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007344os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7345/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007346{
Victor Stinner8c62be82010-05-06 00:08:46 +00007347 if (setreuid(ruid, euid) < 0) {
7348 return posix_error();
7349 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007350 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007352}
7353#endif /* HAVE_SETREUID */
7354
Larry Hastings2f936352014-08-05 14:04:04 +10007355
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007356#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007357/*[clinic input]
7358os.setregid
7359
7360 rgid: gid_t
7361 egid: gid_t
7362 /
7363
7364Set the current process's real and effective group ids.
7365[clinic start generated code]*/
7366
Larry Hastings2f936352014-08-05 14:04:04 +10007367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007368os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7369/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007370{
7371 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007372 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007373 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007374}
7375#endif /* HAVE_SETREGID */
7376
Larry Hastings2f936352014-08-05 14:04:04 +10007377
Guido van Rossumb6775db1994-08-01 11:34:53 +00007378#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007379/*[clinic input]
7380os.setgid
7381 gid: gid_t
7382 /
7383
7384Set the current process's group id.
7385[clinic start generated code]*/
7386
Larry Hastings2f936352014-08-05 14:04:04 +10007387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007388os_setgid_impl(PyObject *module, gid_t gid)
7389/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007390{
Victor Stinner8c62be82010-05-06 00:08:46 +00007391 if (setgid(gid) < 0)
7392 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007393 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007394}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007395#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007396
Larry Hastings2f936352014-08-05 14:04:04 +10007397
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007398#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007399/*[clinic input]
7400os.setgroups
7401
7402 groups: object
7403 /
7404
7405Set the groups of the current process to list.
7406[clinic start generated code]*/
7407
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007408static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007409os_setgroups(PyObject *module, PyObject *groups)
7410/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007411{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007412 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007413 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007414
Victor Stinner8c62be82010-05-06 00:08:46 +00007415 if (!PySequence_Check(groups)) {
7416 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7417 return NULL;
7418 }
7419 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007420 if (len < 0) {
7421 return NULL;
7422 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007423 if (len > MAX_GROUPS) {
7424 PyErr_SetString(PyExc_ValueError, "too many groups");
7425 return NULL;
7426 }
7427 for(i = 0; i < len; i++) {
7428 PyObject *elem;
7429 elem = PySequence_GetItem(groups, i);
7430 if (!elem)
7431 return NULL;
7432 if (!PyLong_Check(elem)) {
7433 PyErr_SetString(PyExc_TypeError,
7434 "groups must be integers");
7435 Py_DECREF(elem);
7436 return NULL;
7437 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007438 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007439 Py_DECREF(elem);
7440 return NULL;
7441 }
7442 }
7443 Py_DECREF(elem);
7444 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007445
Victor Stinner8c62be82010-05-06 00:08:46 +00007446 if (setgroups(len, grouplist) < 0)
7447 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007448 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007449}
7450#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007451
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007452#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7453static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007454wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007455{
Victor Stinner8c62be82010-05-06 00:08:46 +00007456 PyObject *result;
7457 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007458 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007459
Victor Stinner8c62be82010-05-06 00:08:46 +00007460 if (pid == -1)
7461 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007462
Victor Stinner8c62be82010-05-06 00:08:46 +00007463 if (struct_rusage == NULL) {
7464 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7465 if (m == NULL)
7466 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007467 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007468 Py_DECREF(m);
7469 if (struct_rusage == NULL)
7470 return NULL;
7471 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007472
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7474 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7475 if (!result)
7476 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007477
7478#ifndef doubletime
7479#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7480#endif
7481
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007483 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007484 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007485 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007486#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007487 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7488 SET_INT(result, 2, ru->ru_maxrss);
7489 SET_INT(result, 3, ru->ru_ixrss);
7490 SET_INT(result, 4, ru->ru_idrss);
7491 SET_INT(result, 5, ru->ru_isrss);
7492 SET_INT(result, 6, ru->ru_minflt);
7493 SET_INT(result, 7, ru->ru_majflt);
7494 SET_INT(result, 8, ru->ru_nswap);
7495 SET_INT(result, 9, ru->ru_inblock);
7496 SET_INT(result, 10, ru->ru_oublock);
7497 SET_INT(result, 11, ru->ru_msgsnd);
7498 SET_INT(result, 12, ru->ru_msgrcv);
7499 SET_INT(result, 13, ru->ru_nsignals);
7500 SET_INT(result, 14, ru->ru_nvcsw);
7501 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007502#undef SET_INT
7503
Victor Stinner8c62be82010-05-06 00:08:46 +00007504 if (PyErr_Occurred()) {
7505 Py_DECREF(result);
7506 return NULL;
7507 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007508
Victor Stinner8c62be82010-05-06 00:08:46 +00007509 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007510}
7511#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7512
Larry Hastings2f936352014-08-05 14:04:04 +10007513
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007514#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007515/*[clinic input]
7516os.wait3
7517
7518 options: int
7519Wait for completion of a child process.
7520
7521Returns a tuple of information about the child process:
7522 (pid, status, rusage)
7523[clinic start generated code]*/
7524
Larry Hastings2f936352014-08-05 14:04:04 +10007525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007526os_wait3_impl(PyObject *module, int options)
7527/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007528{
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007531 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 WAIT_TYPE status;
7533 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007534
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007535 do {
7536 Py_BEGIN_ALLOW_THREADS
7537 pid = wait3(&status, options, &ru);
7538 Py_END_ALLOW_THREADS
7539 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7540 if (pid < 0)
7541 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007542
Victor Stinner4195b5c2012-02-08 23:03:19 +01007543 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007544}
7545#endif /* HAVE_WAIT3 */
7546
Larry Hastings2f936352014-08-05 14:04:04 +10007547
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007548#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007549/*[clinic input]
7550
7551os.wait4
7552
7553 pid: pid_t
7554 options: int
7555
7556Wait for completion of a specific child process.
7557
7558Returns a tuple of information about the child process:
7559 (pid, status, rusage)
7560[clinic start generated code]*/
7561
Larry Hastings2f936352014-08-05 14:04:04 +10007562static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007563os_wait4_impl(PyObject *module, pid_t pid, int options)
7564/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007565{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007566 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007568 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 WAIT_TYPE status;
7570 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007571
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007572 do {
7573 Py_BEGIN_ALLOW_THREADS
7574 res = wait4(pid, &status, options, &ru);
7575 Py_END_ALLOW_THREADS
7576 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7577 if (res < 0)
7578 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007579
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007580 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007581}
7582#endif /* HAVE_WAIT4 */
7583
Larry Hastings2f936352014-08-05 14:04:04 +10007584
Ross Lagerwall7807c352011-03-17 20:20:30 +02007585#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007586/*[clinic input]
7587os.waitid
7588
7589 idtype: idtype_t
7590 Must be one of be P_PID, P_PGID or P_ALL.
7591 id: id_t
7592 The id to wait on.
7593 options: int
7594 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7595 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7596 /
7597
7598Returns the result of waiting for a process or processes.
7599
7600Returns either waitid_result or None if WNOHANG is specified and there are
7601no children in a waitable state.
7602[clinic start generated code]*/
7603
Larry Hastings2f936352014-08-05 14:04:04 +10007604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007605os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7606/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007607{
7608 PyObject *result;
7609 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007610 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007611 siginfo_t si;
7612 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007613
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007614 do {
7615 Py_BEGIN_ALLOW_THREADS
7616 res = waitid(idtype, id, &si, options);
7617 Py_END_ALLOW_THREADS
7618 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7619 if (res < 0)
7620 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007621
7622 if (si.si_pid == 0)
7623 Py_RETURN_NONE;
7624
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007625 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007626 if (!result)
7627 return NULL;
7628
7629 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007630 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007631 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7632 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7633 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7634 if (PyErr_Occurred()) {
7635 Py_DECREF(result);
7636 return NULL;
7637 }
7638
7639 return result;
7640}
Larry Hastings2f936352014-08-05 14:04:04 +10007641#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007642
Larry Hastings2f936352014-08-05 14:04:04 +10007643
7644#if defined(HAVE_WAITPID)
7645/*[clinic input]
7646os.waitpid
7647 pid: pid_t
7648 options: int
7649 /
7650
7651Wait for completion of a given child process.
7652
7653Returns a tuple of information regarding the child process:
7654 (pid, status)
7655
7656The options argument is ignored on Windows.
7657[clinic start generated code]*/
7658
Larry Hastings2f936352014-08-05 14:04:04 +10007659static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007660os_waitpid_impl(PyObject *module, pid_t pid, int options)
7661/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007662{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007663 pid_t res;
7664 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007665 WAIT_TYPE status;
7666 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007667
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007668 do {
7669 Py_BEGIN_ALLOW_THREADS
7670 res = waitpid(pid, &status, options);
7671 Py_END_ALLOW_THREADS
7672 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7673 if (res < 0)
7674 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007675
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007676 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007677}
Tim Petersab034fa2002-02-01 11:27:43 +00007678#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007679/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007680/*[clinic input]
7681os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007682 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007683 options: int
7684 /
7685
7686Wait for completion of a given process.
7687
7688Returns a tuple of information regarding the process:
7689 (pid, status << 8)
7690
7691The options argument is ignored on Windows.
7692[clinic start generated code]*/
7693
Larry Hastings2f936352014-08-05 14:04:04 +10007694static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007695os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007696/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007697{
7698 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007699 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007700 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007701
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 do {
7703 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007704 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007705 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007706 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007707 Py_END_ALLOW_THREADS
7708 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007709 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007710 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007711
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007713 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007714}
Larry Hastings2f936352014-08-05 14:04:04 +10007715#endif
7716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007717
Guido van Rossumad0ee831995-03-01 10:34:45 +00007718#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007719/*[clinic input]
7720os.wait
7721
7722Wait for completion of a child process.
7723
7724Returns a tuple of information about the child process:
7725 (pid, status)
7726[clinic start generated code]*/
7727
Larry Hastings2f936352014-08-05 14:04:04 +10007728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007729os_wait_impl(PyObject *module)
7730/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007731{
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007733 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 WAIT_TYPE status;
7735 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007736
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007737 do {
7738 Py_BEGIN_ALLOW_THREADS
7739 pid = wait(&status);
7740 Py_END_ALLOW_THREADS
7741 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7742 if (pid < 0)
7743 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007744
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007746}
Larry Hastings2f936352014-08-05 14:04:04 +10007747#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007749
Larry Hastings9cf065c2012-06-22 16:30:09 -07007750#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007751/*[clinic input]
7752os.readlink
7753
7754 path: path_t
7755 *
7756 dir_fd: dir_fd(requires='readlinkat') = None
7757
7758Return a string representing the path to which the symbolic link points.
7759
7760If dir_fd is not None, it should be a file descriptor open to a directory,
7761and path should be relative; path will then be relative to that directory.
7762
7763dir_fd may not be implemented on your platform. If it is unavailable,
7764using it will raise a NotImplementedError.
7765[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007766
Barry Warsaw53699e91996-12-10 23:23:01 +00007767static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007768os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7769/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007770{
Berker Peksage0b5b202018-08-15 13:03:41 +03007771#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007772 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007773 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007774
7775 Py_BEGIN_ALLOW_THREADS
7776#ifdef HAVE_READLINKAT
7777 if (dir_fd != DEFAULT_DIR_FD)
7778 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7779 else
7780#endif
7781 length = readlink(path->narrow, buffer, MAXPATHLEN);
7782 Py_END_ALLOW_THREADS
7783
7784 if (length < 0) {
7785 return path_error(path);
7786 }
7787 buffer[length] = '\0';
7788
7789 if (PyUnicode_Check(path->object))
7790 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7791 else
7792 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007793#elif defined(MS_WINDOWS)
7794 DWORD n_bytes_returned;
7795 DWORD io_result;
7796 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007797 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7798 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7799 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007800 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007801
Larry Hastings2f936352014-08-05 14:04:04 +10007802 /* First get a handle to the reparse point */
7803 Py_BEGIN_ALLOW_THREADS
7804 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007805 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007806 0,
7807 0,
7808 0,
7809 OPEN_EXISTING,
7810 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7811 0);
7812 Py_END_ALLOW_THREADS
7813
Berker Peksage0b5b202018-08-15 13:03:41 +03007814 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007815 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007816 }
Larry Hastings2f936352014-08-05 14:04:04 +10007817
7818 Py_BEGIN_ALLOW_THREADS
7819 /* New call DeviceIoControl to read the reparse point */
7820 io_result = DeviceIoControl(
7821 reparse_point_handle,
7822 FSCTL_GET_REPARSE_POINT,
7823 0, 0, /* in buffer */
7824 target_buffer, sizeof(target_buffer),
7825 &n_bytes_returned,
7826 0 /* we're not using OVERLAPPED_IO */
7827 );
7828 CloseHandle(reparse_point_handle);
7829 Py_END_ALLOW_THREADS
7830
Berker Peksage0b5b202018-08-15 13:03:41 +03007831 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007832 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007833 }
Larry Hastings2f936352014-08-05 14:04:04 +10007834
7835 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7836 {
7837 PyErr_SetString(PyExc_ValueError,
7838 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007839 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007840 }
SSE43c34aad2018-02-13 00:10:35 +07007841 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7842 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007843
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007844 result = PyUnicode_FromWideChar(print_name,
7845 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7846 if (path->narrow) {
7847 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007848 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007849 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007850#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007851}
Berker Peksage0b5b202018-08-15 13:03:41 +03007852#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007853
Larry Hastings9cf065c2012-06-22 16:30:09 -07007854#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007855
7856#if defined(MS_WINDOWS)
7857
Steve Dower6921e732018-03-05 14:26:08 -08007858/* Remove the last portion of the path - return 0 on success */
7859static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007860_dirnameW(WCHAR *path)
7861{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007862 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007863 size_t length = wcsnlen_s(path, MAX_PATH);
7864 if (length == MAX_PATH) {
7865 return -1;
7866 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007867
7868 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007869 for(ptr = path + length; ptr != path; ptr--) {
7870 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007871 break;
Steve Dower6921e732018-03-05 14:26:08 -08007872 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007873 }
7874 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007875 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007876}
7877
Victor Stinner31b3b922013-06-05 01:49:17 +02007878/* Is this path absolute? */
7879static int
7880_is_absW(const WCHAR *path)
7881{
Steve Dower6921e732018-03-05 14:26:08 -08007882 return path[0] == L'\\' || path[0] == L'/' ||
7883 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007884}
7885
Steve Dower6921e732018-03-05 14:26:08 -08007886/* join root and rest with a backslash - return 0 on success */
7887static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007888_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7889{
Victor Stinner31b3b922013-06-05 01:49:17 +02007890 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007891 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007892 }
7893
Steve Dower6921e732018-03-05 14:26:08 -08007894 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7895 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007896 }
Steve Dower6921e732018-03-05 14:26:08 -08007897
7898 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7899 return -1;
7900 }
7901
7902 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007903}
7904
Victor Stinner31b3b922013-06-05 01:49:17 +02007905/* Return True if the path at src relative to dest is a directory */
7906static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007907_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007908{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007909 WIN32_FILE_ATTRIBUTE_DATA src_info;
7910 WCHAR dest_parent[MAX_PATH];
7911 WCHAR src_resolved[MAX_PATH] = L"";
7912
7913 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007914 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7915 _dirnameW(dest_parent)) {
7916 return 0;
7917 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007918 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007919 if (_joinW(src_resolved, dest_parent, src)) {
7920 return 0;
7921 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007922 return (
7923 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7924 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7925 );
7926}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007927#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007928
Larry Hastings2f936352014-08-05 14:04:04 +10007929
7930/*[clinic input]
7931os.symlink
7932 src: path_t
7933 dst: path_t
7934 target_is_directory: bool = False
7935 *
7936 dir_fd: dir_fd(requires='symlinkat')=None
7937
7938# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7939
7940Create a symbolic link pointing to src named dst.
7941
7942target_is_directory is required on Windows if the target is to be
7943 interpreted as a directory. (On Windows, symlink requires
7944 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7945 target_is_directory is ignored on non-Windows platforms.
7946
7947If dir_fd is not None, it should be a file descriptor open to a directory,
7948 and path should be relative; path will then be relative to that directory.
7949dir_fd may not be implemented on your platform.
7950 If it is unavailable, using it will raise a NotImplementedError.
7951
7952[clinic start generated code]*/
7953
Larry Hastings2f936352014-08-05 14:04:04 +10007954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007955os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007956 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007957/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007958{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007959#ifdef MS_WINDOWS
7960 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007961 DWORD flags = 0;
7962
7963 /* Assumed true, set to false if detected to not be available. */
7964 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007965#else
7966 int result;
7967#endif
7968
Larry Hastings9cf065c2012-06-22 16:30:09 -07007969#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007970
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007971 if (windows_has_symlink_unprivileged_flag) {
7972 /* Allow non-admin symlinks if system allows it. */
7973 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7974 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007975
Larry Hastings9cf065c2012-06-22 16:30:09 -07007976 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007977 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007978 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7979 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7980 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7981 }
7982
7983 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007984 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007985 Py_END_ALLOW_THREADS
7986
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007987 if (windows_has_symlink_unprivileged_flag && !result &&
7988 ERROR_INVALID_PARAMETER == GetLastError()) {
7989
7990 Py_BEGIN_ALLOW_THREADS
7991 _Py_BEGIN_SUPPRESS_IPH
7992 /* This error might be caused by
7993 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7994 Try again, and update windows_has_symlink_unprivileged_flag if we
7995 are successful this time.
7996
7997 NOTE: There is a risk of a race condition here if there are other
7998 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7999 another process (or thread) changes that condition in between our
8000 calls to CreateSymbolicLink.
8001 */
8002 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8003 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8004 _Py_END_SUPPRESS_IPH
8005 Py_END_ALLOW_THREADS
8006
8007 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8008 windows_has_symlink_unprivileged_flag = FALSE;
8009 }
8010 }
8011
Larry Hastings2f936352014-08-05 14:04:04 +10008012 if (!result)
8013 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008014
8015#else
8016
Steve Dower6921e732018-03-05 14:26:08 -08008017 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8018 PyErr_SetString(PyExc_ValueError,
8019 "symlink: src and dst must be the same type");
8020 return NULL;
8021 }
8022
Larry Hastings9cf065c2012-06-22 16:30:09 -07008023 Py_BEGIN_ALLOW_THREADS
8024#if HAVE_SYMLINKAT
8025 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008026 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008027 else
8028#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008029 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008030 Py_END_ALLOW_THREADS
8031
Larry Hastings2f936352014-08-05 14:04:04 +10008032 if (result)
8033 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008034#endif
8035
Larry Hastings2f936352014-08-05 14:04:04 +10008036 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008037}
8038#endif /* HAVE_SYMLINK */
8039
Larry Hastings9cf065c2012-06-22 16:30:09 -07008040
Brian Curtind40e6f72010-07-08 21:39:08 +00008041
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008042
Larry Hastings605a62d2012-06-24 04:33:36 -07008043static PyStructSequence_Field times_result_fields[] = {
8044 {"user", "user time"},
8045 {"system", "system time"},
8046 {"children_user", "user time of children"},
8047 {"children_system", "system time of children"},
8048 {"elapsed", "elapsed time since an arbitrary point in the past"},
8049 {NULL}
8050};
8051
8052PyDoc_STRVAR(times_result__doc__,
8053"times_result: Result from os.times().\n\n\
8054This object may be accessed either as a tuple of\n\
8055 (user, system, children_user, children_system, elapsed),\n\
8056or via the attributes user, system, children_user, children_system,\n\
8057and elapsed.\n\
8058\n\
8059See os.times for more information.");
8060
8061static PyStructSequence_Desc times_result_desc = {
8062 "times_result", /* name */
8063 times_result__doc__, /* doc */
8064 times_result_fields,
8065 5
8066};
8067
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008068static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07008069
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008070#ifdef MS_WINDOWS
8071#define HAVE_TIMES /* mandatory, for the method table */
8072#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008073
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008074#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008075
8076static PyObject *
8077build_times_result(double user, double system,
8078 double children_user, double children_system,
8079 double elapsed)
8080{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008081 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008082 if (value == NULL)
8083 return NULL;
8084
8085#define SET(i, field) \
8086 { \
8087 PyObject *o = PyFloat_FromDouble(field); \
8088 if (!o) { \
8089 Py_DECREF(value); \
8090 return NULL; \
8091 } \
8092 PyStructSequence_SET_ITEM(value, i, o); \
8093 } \
8094
8095 SET(0, user);
8096 SET(1, system);
8097 SET(2, children_user);
8098 SET(3, children_system);
8099 SET(4, elapsed);
8100
8101#undef SET
8102
8103 return value;
8104}
8105
Larry Hastings605a62d2012-06-24 04:33:36 -07008106
Larry Hastings2f936352014-08-05 14:04:04 +10008107#ifndef MS_WINDOWS
8108#define NEED_TICKS_PER_SECOND
8109static long ticks_per_second = -1;
8110#endif /* MS_WINDOWS */
8111
8112/*[clinic input]
8113os.times
8114
8115Return a collection containing process timing information.
8116
8117The object returned behaves like a named tuple with these fields:
8118 (utime, stime, cutime, cstime, elapsed_time)
8119All fields are floating point numbers.
8120[clinic start generated code]*/
8121
Larry Hastings2f936352014-08-05 14:04:04 +10008122static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008123os_times_impl(PyObject *module)
8124/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008125#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008126{
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 FILETIME create, exit, kernel, user;
8128 HANDLE hProc;
8129 hProc = GetCurrentProcess();
8130 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8131 /* The fields of a FILETIME structure are the hi and lo part
8132 of a 64-bit value expressed in 100 nanosecond units.
8133 1e7 is one second in such units; 1e-7 the inverse.
8134 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8135 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008136 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008137 (double)(user.dwHighDateTime*429.4967296 +
8138 user.dwLowDateTime*1e-7),
8139 (double)(kernel.dwHighDateTime*429.4967296 +
8140 kernel.dwLowDateTime*1e-7),
8141 (double)0,
8142 (double)0,
8143 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008144}
Larry Hastings2f936352014-08-05 14:04:04 +10008145#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008146{
Larry Hastings2f936352014-08-05 14:04:04 +10008147
8148
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008149 struct tms t;
8150 clock_t c;
8151 errno = 0;
8152 c = times(&t);
8153 if (c == (clock_t) -1)
8154 return posix_error();
8155 return build_times_result(
8156 (double)t.tms_utime / ticks_per_second,
8157 (double)t.tms_stime / ticks_per_second,
8158 (double)t.tms_cutime / ticks_per_second,
8159 (double)t.tms_cstime / ticks_per_second,
8160 (double)c / ticks_per_second);
8161}
Larry Hastings2f936352014-08-05 14:04:04 +10008162#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008163#endif /* HAVE_TIMES */
8164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008165
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008166#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008167/*[clinic input]
8168os.getsid
8169
8170 pid: pid_t
8171 /
8172
8173Call the system call getsid(pid) and return the result.
8174[clinic start generated code]*/
8175
Larry Hastings2f936352014-08-05 14:04:04 +10008176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008177os_getsid_impl(PyObject *module, pid_t pid)
8178/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008179{
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 sid = getsid(pid);
8182 if (sid < 0)
8183 return posix_error();
8184 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008185}
8186#endif /* HAVE_GETSID */
8187
8188
Guido van Rossumb6775db1994-08-01 11:34:53 +00008189#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008190/*[clinic input]
8191os.setsid
8192
8193Call the system call setsid().
8194[clinic start generated code]*/
8195
Larry Hastings2f936352014-08-05 14:04:04 +10008196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008197os_setsid_impl(PyObject *module)
8198/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008199{
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 if (setsid() < 0)
8201 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008202 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008203}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008204#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008205
Larry Hastings2f936352014-08-05 14:04:04 +10008206
Guido van Rossumb6775db1994-08-01 11:34:53 +00008207#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008208/*[clinic input]
8209os.setpgid
8210
8211 pid: pid_t
8212 pgrp: pid_t
8213 /
8214
8215Call the system call setpgid(pid, pgrp).
8216[clinic start generated code]*/
8217
Larry Hastings2f936352014-08-05 14:04:04 +10008218static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008219os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8220/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008221{
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 if (setpgid(pid, pgrp) < 0)
8223 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008224 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008225}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008226#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008228
Guido van Rossumb6775db1994-08-01 11:34:53 +00008229#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008230/*[clinic input]
8231os.tcgetpgrp
8232
8233 fd: int
8234 /
8235
8236Return the process group associated with the terminal specified by fd.
8237[clinic start generated code]*/
8238
Larry Hastings2f936352014-08-05 14:04:04 +10008239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008240os_tcgetpgrp_impl(PyObject *module, int fd)
8241/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008242{
8243 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 if (pgid < 0)
8245 return posix_error();
8246 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008247}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008248#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008249
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008250
Guido van Rossumb6775db1994-08-01 11:34:53 +00008251#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008252/*[clinic input]
8253os.tcsetpgrp
8254
8255 fd: int
8256 pgid: pid_t
8257 /
8258
8259Set the process group associated with the terminal specified by fd.
8260[clinic start generated code]*/
8261
Larry Hastings2f936352014-08-05 14:04:04 +10008262static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008263os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8264/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008265{
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 if (tcsetpgrp(fd, pgid) < 0)
8267 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008268 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008269}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008270#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008271
Guido van Rossum687dd131993-05-17 08:34:16 +00008272/* Functions acting on file descriptors */
8273
Victor Stinnerdaf45552013-08-28 00:53:59 +02008274#ifdef O_CLOEXEC
8275extern int _Py_open_cloexec_works;
8276#endif
8277
Larry Hastings2f936352014-08-05 14:04:04 +10008278
8279/*[clinic input]
8280os.open -> int
8281 path: path_t
8282 flags: int
8283 mode: int = 0o777
8284 *
8285 dir_fd: dir_fd(requires='openat') = None
8286
8287# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8288
8289Open a file for low level IO. Returns a file descriptor (integer).
8290
8291If dir_fd is not None, it should be a file descriptor open to a directory,
8292 and path should be relative; path will then be relative to that directory.
8293dir_fd may not be implemented on your platform.
8294 If it is unavailable, using it will raise a NotImplementedError.
8295[clinic start generated code]*/
8296
Larry Hastings2f936352014-08-05 14:04:04 +10008297static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008298os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8299/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008300{
8301 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008302 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008303
Victor Stinnerdaf45552013-08-28 00:53:59 +02008304#ifdef O_CLOEXEC
8305 int *atomic_flag_works = &_Py_open_cloexec_works;
8306#elif !defined(MS_WINDOWS)
8307 int *atomic_flag_works = NULL;
8308#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008309
Victor Stinnerdaf45552013-08-28 00:53:59 +02008310#ifdef MS_WINDOWS
8311 flags |= O_NOINHERIT;
8312#elif defined(O_CLOEXEC)
8313 flags |= O_CLOEXEC;
8314#endif
8315
Steve Dowerb82e17e2019-05-23 08:45:22 -07008316 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8317 return -1;
8318 }
8319
Steve Dower8fc89802015-04-12 00:26:27 -04008320 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008321 do {
8322 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008323#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008324 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008325#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008326#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008327 if (dir_fd != DEFAULT_DIR_FD)
8328 fd = openat(dir_fd, path->narrow, flags, mode);
8329 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008330#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008331 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008332#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008333 Py_END_ALLOW_THREADS
8334 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008335 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008336
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008337 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008338 if (!async_err)
8339 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008340 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008341 }
8342
Victor Stinnerdaf45552013-08-28 00:53:59 +02008343#ifndef MS_WINDOWS
8344 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8345 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008346 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008347 }
8348#endif
8349
Larry Hastings2f936352014-08-05 14:04:04 +10008350 return fd;
8351}
8352
8353
8354/*[clinic input]
8355os.close
8356
8357 fd: int
8358
8359Close a file descriptor.
8360[clinic start generated code]*/
8361
Barry Warsaw53699e91996-12-10 23:23:01 +00008362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008363os_close_impl(PyObject *module, int fd)
8364/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008365{
Larry Hastings2f936352014-08-05 14:04:04 +10008366 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008367 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8368 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8369 * for more details.
8370 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008371 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008372 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008374 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008375 Py_END_ALLOW_THREADS
8376 if (res < 0)
8377 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008378 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008379}
8380
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008381
Larry Hastings2f936352014-08-05 14:04:04 +10008382/*[clinic input]
8383os.closerange
8384
8385 fd_low: int
8386 fd_high: int
8387 /
8388
8389Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8390[clinic start generated code]*/
8391
Larry Hastings2f936352014-08-05 14:04:04 +10008392static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008393os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8394/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008395{
8396 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008398 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008399 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008400 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008401 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 Py_END_ALLOW_THREADS
8403 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008404}
8405
8406
Larry Hastings2f936352014-08-05 14:04:04 +10008407/*[clinic input]
8408os.dup -> int
8409
8410 fd: int
8411 /
8412
8413Return a duplicate of a file descriptor.
8414[clinic start generated code]*/
8415
Larry Hastings2f936352014-08-05 14:04:04 +10008416static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008417os_dup_impl(PyObject *module, int fd)
8418/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008419{
8420 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008421}
8422
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008423
Larry Hastings2f936352014-08-05 14:04:04 +10008424/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008425os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008426 fd: int
8427 fd2: int
8428 inheritable: bool=True
8429
8430Duplicate file descriptor.
8431[clinic start generated code]*/
8432
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008433static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008434os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008435/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008436{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008437 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008438#if defined(HAVE_DUP3) && \
8439 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8440 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008441 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008442#endif
8443
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008444 if (fd < 0 || fd2 < 0) {
8445 posix_error();
8446 return -1;
8447 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008448
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008449 /* dup2() can fail with EINTR if the target FD is already open, because it
8450 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8451 * upon close(), and therefore below.
8452 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008453#ifdef MS_WINDOWS
8454 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008455 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008456 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008457 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008458 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008459 if (res < 0) {
8460 posix_error();
8461 return -1;
8462 }
8463 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008464
8465 /* Character files like console cannot be make non-inheritable */
8466 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8467 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008468 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008469 }
8470
8471#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8472 Py_BEGIN_ALLOW_THREADS
8473 if (!inheritable)
8474 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8475 else
8476 res = dup2(fd, fd2);
8477 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008478 if (res < 0) {
8479 posix_error();
8480 return -1;
8481 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008482
8483#else
8484
8485#ifdef HAVE_DUP3
8486 if (!inheritable && dup3_works != 0) {
8487 Py_BEGIN_ALLOW_THREADS
8488 res = dup3(fd, fd2, O_CLOEXEC);
8489 Py_END_ALLOW_THREADS
8490 if (res < 0) {
8491 if (dup3_works == -1)
8492 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008493 if (dup3_works) {
8494 posix_error();
8495 return -1;
8496 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008497 }
8498 }
8499
8500 if (inheritable || dup3_works == 0)
8501 {
8502#endif
8503 Py_BEGIN_ALLOW_THREADS
8504 res = dup2(fd, fd2);
8505 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008506 if (res < 0) {
8507 posix_error();
8508 return -1;
8509 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008510
8511 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8512 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008513 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008514 }
8515#ifdef HAVE_DUP3
8516 }
8517#endif
8518
8519#endif
8520
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008521 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008522}
8523
Larry Hastings2f936352014-08-05 14:04:04 +10008524
Ross Lagerwall7807c352011-03-17 20:20:30 +02008525#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008526/*[clinic input]
8527os.lockf
8528
8529 fd: int
8530 An open file descriptor.
8531 command: int
8532 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8533 length: Py_off_t
8534 The number of bytes to lock, starting at the current position.
8535 /
8536
8537Apply, test or remove a POSIX lock on an open file descriptor.
8538
8539[clinic start generated code]*/
8540
Larry Hastings2f936352014-08-05 14:04:04 +10008541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008542os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8543/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008544{
8545 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008546
8547 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008548 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008549 Py_END_ALLOW_THREADS
8550
8551 if (res < 0)
8552 return posix_error();
8553
8554 Py_RETURN_NONE;
8555}
Larry Hastings2f936352014-08-05 14:04:04 +10008556#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008558
Larry Hastings2f936352014-08-05 14:04:04 +10008559/*[clinic input]
8560os.lseek -> Py_off_t
8561
8562 fd: int
8563 position: Py_off_t
8564 how: int
8565 /
8566
8567Set the position of a file descriptor. Return the new position.
8568
8569Return the new cursor position in number of bytes
8570relative to the beginning of the file.
8571[clinic start generated code]*/
8572
Larry Hastings2f936352014-08-05 14:04:04 +10008573static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008574os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8575/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008576{
8577 Py_off_t result;
8578
Guido van Rossum687dd131993-05-17 08:34:16 +00008579#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8581 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008582 case 0: how = SEEK_SET; break;
8583 case 1: how = SEEK_CUR; break;
8584 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008585 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008586#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008587
Victor Stinner8c62be82010-05-06 00:08:46 +00008588 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008589 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008590#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008591 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008592#else
Larry Hastings2f936352014-08-05 14:04:04 +10008593 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008594#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008595 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008596 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008597 if (result < 0)
8598 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008599
Larry Hastings2f936352014-08-05 14:04:04 +10008600 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008601}
8602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008603
Larry Hastings2f936352014-08-05 14:04:04 +10008604/*[clinic input]
8605os.read
8606 fd: int
8607 length: Py_ssize_t
8608 /
8609
8610Read from a file descriptor. Returns a bytes object.
8611[clinic start generated code]*/
8612
Larry Hastings2f936352014-08-05 14:04:04 +10008613static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008614os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8615/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008616{
Victor Stinner8c62be82010-05-06 00:08:46 +00008617 Py_ssize_t n;
8618 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008619
8620 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008621 errno = EINVAL;
8622 return posix_error();
8623 }
Larry Hastings2f936352014-08-05 14:04:04 +10008624
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008625 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008626
8627 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 if (buffer == NULL)
8629 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008630
Victor Stinner66aab0c2015-03-19 22:53:20 +01008631 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8632 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008634 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 }
Larry Hastings2f936352014-08-05 14:04:04 +10008636
8637 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008638 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008639
Victor Stinner8c62be82010-05-06 00:08:46 +00008640 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008641}
8642
Ross Lagerwall7807c352011-03-17 20:20:30 +02008643#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008644 || defined(__APPLE__))) \
8645 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8646 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8647static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008648iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008649{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008650 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008651
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008652 *iov = PyMem_New(struct iovec, cnt);
8653 if (*iov == NULL) {
8654 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008655 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008656 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008657
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008658 *buf = PyMem_New(Py_buffer, cnt);
8659 if (*buf == NULL) {
8660 PyMem_Del(*iov);
8661 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008662 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008663 }
8664
8665 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008666 PyObject *item = PySequence_GetItem(seq, i);
8667 if (item == NULL)
8668 goto fail;
8669 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8670 Py_DECREF(item);
8671 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008672 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008673 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008674 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008675 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008676 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008677 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008678
8679fail:
8680 PyMem_Del(*iov);
8681 for (j = 0; j < i; j++) {
8682 PyBuffer_Release(&(*buf)[j]);
8683 }
8684 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008685 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008686}
8687
8688static void
8689iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8690{
8691 int i;
8692 PyMem_Del(iov);
8693 for (i = 0; i < cnt; i++) {
8694 PyBuffer_Release(&buf[i]);
8695 }
8696 PyMem_Del(buf);
8697}
8698#endif
8699
Larry Hastings2f936352014-08-05 14:04:04 +10008700
Ross Lagerwall7807c352011-03-17 20:20:30 +02008701#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008702/*[clinic input]
8703os.readv -> Py_ssize_t
8704
8705 fd: int
8706 buffers: object
8707 /
8708
8709Read from a file descriptor fd into an iterable of buffers.
8710
8711The buffers should be mutable buffers accepting bytes.
8712readv will transfer data into each buffer until it is full
8713and then move on to the next buffer in the sequence to hold
8714the rest of the data.
8715
8716readv returns the total number of bytes read,
8717which may be less than the total capacity of all the buffers.
8718[clinic start generated code]*/
8719
Larry Hastings2f936352014-08-05 14:04:04 +10008720static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008721os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8722/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008723{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008724 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008725 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008726 struct iovec *iov;
8727 Py_buffer *buf;
8728
Larry Hastings2f936352014-08-05 14:04:04 +10008729 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008730 PyErr_SetString(PyExc_TypeError,
8731 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008732 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008733 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008734
Larry Hastings2f936352014-08-05 14:04:04 +10008735 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008736 if (cnt < 0)
8737 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008738
8739 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8740 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008741
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008742 do {
8743 Py_BEGIN_ALLOW_THREADS
8744 n = readv(fd, iov, cnt);
8745 Py_END_ALLOW_THREADS
8746 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008747
8748 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008749 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008750 if (!async_err)
8751 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008752 return -1;
8753 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008754
Larry Hastings2f936352014-08-05 14:04:04 +10008755 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008756}
Larry Hastings2f936352014-08-05 14:04:04 +10008757#endif /* HAVE_READV */
8758
Ross Lagerwall7807c352011-03-17 20:20:30 +02008759
8760#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008761/*[clinic input]
8762# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8763os.pread
8764
8765 fd: int
8766 length: int
8767 offset: Py_off_t
8768 /
8769
8770Read a number of bytes from a file descriptor starting at a particular offset.
8771
8772Read length bytes from file descriptor fd, starting at offset bytes from
8773the beginning of the file. The file offset remains unchanged.
8774[clinic start generated code]*/
8775
Larry Hastings2f936352014-08-05 14:04:04 +10008776static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008777os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8778/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008779{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008780 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008781 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008782 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008783
Larry Hastings2f936352014-08-05 14:04:04 +10008784 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008785 errno = EINVAL;
8786 return posix_error();
8787 }
Larry Hastings2f936352014-08-05 14:04:04 +10008788 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008789 if (buffer == NULL)
8790 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008791
8792 do {
8793 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008794 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008795 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008796 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008797 Py_END_ALLOW_THREADS
8798 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8799
Ross Lagerwall7807c352011-03-17 20:20:30 +02008800 if (n < 0) {
8801 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008802 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008803 }
Larry Hastings2f936352014-08-05 14:04:04 +10008804 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008805 _PyBytes_Resize(&buffer, n);
8806 return buffer;
8807}
Larry Hastings2f936352014-08-05 14:04:04 +10008808#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008809
Pablo Galindo4defba32018-01-27 16:16:37 +00008810#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8811/*[clinic input]
8812os.preadv -> Py_ssize_t
8813
8814 fd: int
8815 buffers: object
8816 offset: Py_off_t
8817 flags: int = 0
8818 /
8819
8820Reads from a file descriptor into a number of mutable bytes-like objects.
8821
8822Combines the functionality of readv() and pread(). As readv(), it will
8823transfer data into each buffer until it is full and then move on to the next
8824buffer in the sequence to hold the rest of the data. Its fourth argument,
8825specifies the file offset at which the input operation is to be performed. It
8826will return the total number of bytes read (which can be less than the total
8827capacity of all the objects).
8828
8829The flags argument contains a bitwise OR of zero or more of the following flags:
8830
8831- RWF_HIPRI
8832- RWF_NOWAIT
8833
8834Using non-zero flags requires Linux 4.6 or newer.
8835[clinic start generated code]*/
8836
8837static Py_ssize_t
8838os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8839 int flags)
8840/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8841{
8842 Py_ssize_t cnt, n;
8843 int async_err = 0;
8844 struct iovec *iov;
8845 Py_buffer *buf;
8846
8847 if (!PySequence_Check(buffers)) {
8848 PyErr_SetString(PyExc_TypeError,
8849 "preadv2() arg 2 must be a sequence");
8850 return -1;
8851 }
8852
8853 cnt = PySequence_Size(buffers);
8854 if (cnt < 0) {
8855 return -1;
8856 }
8857
8858#ifndef HAVE_PREADV2
8859 if(flags != 0) {
8860 argument_unavailable_error("preadv2", "flags");
8861 return -1;
8862 }
8863#endif
8864
8865 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8866 return -1;
8867 }
8868#ifdef HAVE_PREADV2
8869 do {
8870 Py_BEGIN_ALLOW_THREADS
8871 _Py_BEGIN_SUPPRESS_IPH
8872 n = preadv2(fd, iov, cnt, offset, flags);
8873 _Py_END_SUPPRESS_IPH
8874 Py_END_ALLOW_THREADS
8875 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8876#else
8877 do {
8878 Py_BEGIN_ALLOW_THREADS
8879 _Py_BEGIN_SUPPRESS_IPH
8880 n = preadv(fd, iov, cnt, offset);
8881 _Py_END_SUPPRESS_IPH
8882 Py_END_ALLOW_THREADS
8883 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8884#endif
8885
8886 iov_cleanup(iov, buf, cnt);
8887 if (n < 0) {
8888 if (!async_err) {
8889 posix_error();
8890 }
8891 return -1;
8892 }
8893
8894 return n;
8895}
8896#endif /* HAVE_PREADV */
8897
Larry Hastings2f936352014-08-05 14:04:04 +10008898
8899/*[clinic input]
8900os.write -> Py_ssize_t
8901
8902 fd: int
8903 data: Py_buffer
8904 /
8905
8906Write a bytes object to a file descriptor.
8907[clinic start generated code]*/
8908
Larry Hastings2f936352014-08-05 14:04:04 +10008909static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008910os_write_impl(PyObject *module, int fd, Py_buffer *data)
8911/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008912{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008913 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008914}
8915
8916#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008917PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008918"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008919sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008920 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008921Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008922
Larry Hastings2f936352014-08-05 14:04:04 +10008923/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008924static PyObject *
8925posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8926{
8927 int in, out;
8928 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008929 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008930 off_t offset;
8931
8932#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8933#ifndef __APPLE__
8934 Py_ssize_t len;
8935#endif
8936 PyObject *headers = NULL, *trailers = NULL;
8937 Py_buffer *hbuf, *tbuf;
8938 off_t sbytes;
8939 struct sf_hdtr sf;
8940 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008941 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008942 static char *keywords[] = {"out", "in",
8943 "offset", "count",
8944 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008945
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008946 sf.headers = NULL;
8947 sf.trailers = NULL;
8948
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008949#ifdef __APPLE__
8950 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008951 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008952#else
8953 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008954 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008955#endif
8956 &headers, &trailers, &flags))
8957 return NULL;
8958 if (headers != NULL) {
8959 if (!PySequence_Check(headers)) {
8960 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008961 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008962 return NULL;
8963 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008964 Py_ssize_t i = PySequence_Size(headers);
8965 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008966 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008967 if (i > INT_MAX) {
8968 PyErr_SetString(PyExc_OverflowError,
8969 "sendfile() header is too large");
8970 return NULL;
8971 }
8972 if (i > 0) {
8973 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008974 if (iov_setup(&(sf.headers), &hbuf,
8975 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008976 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008977#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008978 for (i = 0; i < sf.hdr_cnt; i++) {
8979 Py_ssize_t blen = sf.headers[i].iov_len;
8980# define OFF_T_MAX 0x7fffffffffffffff
8981 if (sbytes >= OFF_T_MAX - blen) {
8982 PyErr_SetString(PyExc_OverflowError,
8983 "sendfile() header is too large");
8984 return NULL;
8985 }
8986 sbytes += blen;
8987 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008988#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008989 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008990 }
8991 }
8992 if (trailers != NULL) {
8993 if (!PySequence_Check(trailers)) {
8994 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008995 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008996 return NULL;
8997 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008998 Py_ssize_t i = PySequence_Size(trailers);
8999 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009000 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009001 if (i > INT_MAX) {
9002 PyErr_SetString(PyExc_OverflowError,
9003 "sendfile() trailer is too large");
9004 return NULL;
9005 }
9006 if (i > 0) {
9007 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009008 if (iov_setup(&(sf.trailers), &tbuf,
9009 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009010 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009011 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009012 }
9013 }
9014
Steve Dower8fc89802015-04-12 00:26:27 -04009015 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009016 do {
9017 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009018#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009019 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009020#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009021 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009022#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009023 Py_END_ALLOW_THREADS
9024 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009025 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009026
9027 if (sf.headers != NULL)
9028 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9029 if (sf.trailers != NULL)
9030 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9031
9032 if (ret < 0) {
9033 if ((errno == EAGAIN) || (errno == EBUSY)) {
9034 if (sbytes != 0) {
9035 // some data has been sent
9036 goto done;
9037 }
9038 else {
9039 // no data has been sent; upper application is supposed
9040 // to retry on EAGAIN or EBUSY
9041 return posix_error();
9042 }
9043 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009044 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009045 }
9046 goto done;
9047
9048done:
9049 #if !defined(HAVE_LARGEFILE_SUPPORT)
9050 return Py_BuildValue("l", sbytes);
9051 #else
9052 return Py_BuildValue("L", sbytes);
9053 #endif
9054
9055#else
9056 Py_ssize_t count;
9057 PyObject *offobj;
9058 static char *keywords[] = {"out", "in",
9059 "offset", "count", NULL};
9060 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9061 keywords, &out, &in, &offobj, &count))
9062 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009063#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009064 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009065 do {
9066 Py_BEGIN_ALLOW_THREADS
9067 ret = sendfile(out, in, NULL, count);
9068 Py_END_ALLOW_THREADS
9069 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009070 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009071 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009072 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009073 }
9074#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009075 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009076 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009077
9078 do {
9079 Py_BEGIN_ALLOW_THREADS
9080 ret = sendfile(out, in, &offset, count);
9081 Py_END_ALLOW_THREADS
9082 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009083 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009084 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009085 return Py_BuildValue("n", ret);
9086#endif
9087}
Larry Hastings2f936352014-08-05 14:04:04 +10009088#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009089
Larry Hastings2f936352014-08-05 14:04:04 +10009090
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009091#if defined(__APPLE__)
9092/*[clinic input]
9093os._fcopyfile
9094
9095 infd: int
9096 outfd: int
9097 flags: int
9098 /
9099
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009100Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009101[clinic start generated code]*/
9102
9103static PyObject *
9104os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009105/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009106{
9107 int ret;
9108
9109 Py_BEGIN_ALLOW_THREADS
9110 ret = fcopyfile(infd, outfd, NULL, flags);
9111 Py_END_ALLOW_THREADS
9112 if (ret < 0)
9113 return posix_error();
9114 Py_RETURN_NONE;
9115}
9116#endif
9117
9118
Larry Hastings2f936352014-08-05 14:04:04 +10009119/*[clinic input]
9120os.fstat
9121
9122 fd : int
9123
9124Perform a stat system call on the given file descriptor.
9125
9126Like stat(), but for an open file descriptor.
9127Equivalent to os.stat(fd).
9128[clinic start generated code]*/
9129
Larry Hastings2f936352014-08-05 14:04:04 +10009130static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009131os_fstat_impl(PyObject *module, int fd)
9132/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009133{
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 STRUCT_STAT st;
9135 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009136 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009137
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009138 do {
9139 Py_BEGIN_ALLOW_THREADS
9140 res = FSTAT(fd, &st);
9141 Py_END_ALLOW_THREADS
9142 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009144#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009145 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009146#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009147 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009148#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 }
Tim Peters5aa91602002-01-30 05:46:57 +00009150
Victor Stinner4195b5c2012-02-08 23:03:19 +01009151 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009152}
9153
Larry Hastings2f936352014-08-05 14:04:04 +10009154
9155/*[clinic input]
9156os.isatty -> bool
9157 fd: int
9158 /
9159
9160Return True if the fd is connected to a terminal.
9161
9162Return True if the file descriptor is an open file descriptor
9163connected to the slave end of a terminal.
9164[clinic start generated code]*/
9165
Larry Hastings2f936352014-08-05 14:04:04 +10009166static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009167os_isatty_impl(PyObject *module, int fd)
9168/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009169{
Steve Dower8fc89802015-04-12 00:26:27 -04009170 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009171 _Py_BEGIN_SUPPRESS_IPH
9172 return_value = isatty(fd);
9173 _Py_END_SUPPRESS_IPH
9174 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009175}
9176
9177
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009178#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009179/*[clinic input]
9180os.pipe
9181
9182Create a pipe.
9183
9184Returns a tuple of two file descriptors:
9185 (read_fd, write_fd)
9186[clinic start generated code]*/
9187
Larry Hastings2f936352014-08-05 14:04:04 +10009188static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009189os_pipe_impl(PyObject *module)
9190/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009191{
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009193#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009195 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009196 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009197#else
9198 int res;
9199#endif
9200
9201#ifdef MS_WINDOWS
9202 attr.nLength = sizeof(attr);
9203 attr.lpSecurityDescriptor = NULL;
9204 attr.bInheritHandle = FALSE;
9205
9206 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009207 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009208 ok = CreatePipe(&read, &write, &attr, 0);
9209 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009210 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9211 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009212 if (fds[0] == -1 || fds[1] == -1) {
9213 CloseHandle(read);
9214 CloseHandle(write);
9215 ok = 0;
9216 }
9217 }
Steve Dowerc3630612016-11-19 18:41:16 -08009218 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009219 Py_END_ALLOW_THREADS
9220
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009222 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009223#else
9224
9225#ifdef HAVE_PIPE2
9226 Py_BEGIN_ALLOW_THREADS
9227 res = pipe2(fds, O_CLOEXEC);
9228 Py_END_ALLOW_THREADS
9229
9230 if (res != 0 && errno == ENOSYS)
9231 {
9232#endif
9233 Py_BEGIN_ALLOW_THREADS
9234 res = pipe(fds);
9235 Py_END_ALLOW_THREADS
9236
9237 if (res == 0) {
9238 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9239 close(fds[0]);
9240 close(fds[1]);
9241 return NULL;
9242 }
9243 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9244 close(fds[0]);
9245 close(fds[1]);
9246 return NULL;
9247 }
9248 }
9249#ifdef HAVE_PIPE2
9250 }
9251#endif
9252
9253 if (res != 0)
9254 return PyErr_SetFromErrno(PyExc_OSError);
9255#endif /* !MS_WINDOWS */
9256 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009257}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009258#endif /* HAVE_PIPE */
9259
Larry Hastings2f936352014-08-05 14:04:04 +10009260
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009261#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009262/*[clinic input]
9263os.pipe2
9264
9265 flags: int
9266 /
9267
9268Create a pipe with flags set atomically.
9269
9270Returns a tuple of two file descriptors:
9271 (read_fd, write_fd)
9272
9273flags can be constructed by ORing together one or more of these values:
9274O_NONBLOCK, O_CLOEXEC.
9275[clinic start generated code]*/
9276
Larry Hastings2f936352014-08-05 14:04:04 +10009277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009278os_pipe2_impl(PyObject *module, int flags)
9279/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009280{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009281 int fds[2];
9282 int res;
9283
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009284 res = pipe2(fds, flags);
9285 if (res != 0)
9286 return posix_error();
9287 return Py_BuildValue("(ii)", fds[0], fds[1]);
9288}
9289#endif /* HAVE_PIPE2 */
9290
Larry Hastings2f936352014-08-05 14:04:04 +10009291
Ross Lagerwall7807c352011-03-17 20:20:30 +02009292#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009293/*[clinic input]
9294os.writev -> Py_ssize_t
9295 fd: int
9296 buffers: object
9297 /
9298
9299Iterate over buffers, and write the contents of each to a file descriptor.
9300
9301Returns the total number of bytes written.
9302buffers must be a sequence of bytes-like objects.
9303[clinic start generated code]*/
9304
Larry Hastings2f936352014-08-05 14:04:04 +10009305static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009306os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9307/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009308{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009309 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009310 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009311 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009312 struct iovec *iov;
9313 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009314
9315 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009316 PyErr_SetString(PyExc_TypeError,
9317 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009318 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009319 }
Larry Hastings2f936352014-08-05 14:04:04 +10009320 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009321 if (cnt < 0)
9322 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009323
Larry Hastings2f936352014-08-05 14:04:04 +10009324 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9325 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009326 }
9327
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009328 do {
9329 Py_BEGIN_ALLOW_THREADS
9330 result = writev(fd, iov, cnt);
9331 Py_END_ALLOW_THREADS
9332 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009333
9334 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009335 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009336 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009337
Georg Brandl306336b2012-06-24 12:55:33 +02009338 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009339}
Larry Hastings2f936352014-08-05 14:04:04 +10009340#endif /* HAVE_WRITEV */
9341
9342
9343#ifdef HAVE_PWRITE
9344/*[clinic input]
9345os.pwrite -> Py_ssize_t
9346
9347 fd: int
9348 buffer: Py_buffer
9349 offset: Py_off_t
9350 /
9351
9352Write bytes to a file descriptor starting at a particular offset.
9353
9354Write buffer to fd, starting at offset bytes from the beginning of
9355the file. Returns the number of bytes writte. Does not change the
9356current file offset.
9357[clinic start generated code]*/
9358
Larry Hastings2f936352014-08-05 14:04:04 +10009359static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009360os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9361/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009362{
9363 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009364 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009365
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009366 do {
9367 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009368 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009369 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009370 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009371 Py_END_ALLOW_THREADS
9372 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009373
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009374 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009375 posix_error();
9376 return size;
9377}
9378#endif /* HAVE_PWRITE */
9379
Pablo Galindo4defba32018-01-27 16:16:37 +00009380#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9381/*[clinic input]
9382os.pwritev -> Py_ssize_t
9383
9384 fd: int
9385 buffers: object
9386 offset: Py_off_t
9387 flags: int = 0
9388 /
9389
9390Writes the contents of bytes-like objects to a file descriptor at a given offset.
9391
9392Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9393of bytes-like objects. Buffers are processed in array order. Entire contents of first
9394buffer is written before proceeding to second, and so on. The operating system may
9395set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9396This function writes the contents of each object to the file descriptor and returns
9397the total number of bytes written.
9398
9399The flags argument contains a bitwise OR of zero or more of the following flags:
9400
9401- RWF_DSYNC
9402- RWF_SYNC
9403
9404Using non-zero flags requires Linux 4.7 or newer.
9405[clinic start generated code]*/
9406
9407static Py_ssize_t
9408os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9409 int flags)
9410/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9411{
9412 Py_ssize_t cnt;
9413 Py_ssize_t result;
9414 int async_err = 0;
9415 struct iovec *iov;
9416 Py_buffer *buf;
9417
9418 if (!PySequence_Check(buffers)) {
9419 PyErr_SetString(PyExc_TypeError,
9420 "pwritev() arg 2 must be a sequence");
9421 return -1;
9422 }
9423
9424 cnt = PySequence_Size(buffers);
9425 if (cnt < 0) {
9426 return -1;
9427 }
9428
9429#ifndef HAVE_PWRITEV2
9430 if(flags != 0) {
9431 argument_unavailable_error("pwritev2", "flags");
9432 return -1;
9433 }
9434#endif
9435
9436 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9437 return -1;
9438 }
9439#ifdef HAVE_PWRITEV2
9440 do {
9441 Py_BEGIN_ALLOW_THREADS
9442 _Py_BEGIN_SUPPRESS_IPH
9443 result = pwritev2(fd, iov, cnt, offset, flags);
9444 _Py_END_SUPPRESS_IPH
9445 Py_END_ALLOW_THREADS
9446 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9447#else
9448 do {
9449 Py_BEGIN_ALLOW_THREADS
9450 _Py_BEGIN_SUPPRESS_IPH
9451 result = pwritev(fd, iov, cnt, offset);
9452 _Py_END_SUPPRESS_IPH
9453 Py_END_ALLOW_THREADS
9454 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9455#endif
9456
9457 iov_cleanup(iov, buf, cnt);
9458 if (result < 0) {
9459 if (!async_err) {
9460 posix_error();
9461 }
9462 return -1;
9463 }
9464
9465 return result;
9466}
9467#endif /* HAVE_PWRITEV */
9468
Pablo Galindoaac4d032019-05-31 19:39:47 +01009469#ifdef HAVE_COPY_FILE_RANGE
9470/*[clinic input]
9471
9472os.copy_file_range
9473 src: int
9474 Source file descriptor.
9475 dst: int
9476 Destination file descriptor.
9477 count: Py_ssize_t
9478 Number of bytes to copy.
9479 offset_src: object = None
9480 Starting offset in src.
9481 offset_dst: object = None
9482 Starting offset in dst.
9483
9484Copy count bytes from one file descriptor to another.
9485
9486If offset_src is None, then src is read from the current position;
9487respectively for offset_dst.
9488[clinic start generated code]*/
9489
9490static PyObject *
9491os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9492 PyObject *offset_src, PyObject *offset_dst)
9493/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9494{
9495 off_t offset_src_val, offset_dst_val;
9496 off_t *p_offset_src = NULL;
9497 off_t *p_offset_dst = NULL;
9498 Py_ssize_t ret;
9499 int async_err = 0;
9500 /* The flags argument is provided to allow
9501 * for future extensions and currently must be to 0. */
9502 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009503
9504
Pablo Galindoaac4d032019-05-31 19:39:47 +01009505 if (count < 0) {
9506 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9507 return NULL;
9508 }
9509
9510 if (offset_src != Py_None) {
9511 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9512 return NULL;
9513 }
9514 p_offset_src = &offset_src_val;
9515 }
9516
9517 if (offset_dst != Py_None) {
9518 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9519 return NULL;
9520 }
9521 p_offset_dst = &offset_dst_val;
9522 }
9523
9524 do {
9525 Py_BEGIN_ALLOW_THREADS
9526 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9527 Py_END_ALLOW_THREADS
9528 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9529
9530 if (ret < 0) {
9531 return (!async_err) ? posix_error() : NULL;
9532 }
9533
9534 return PyLong_FromSsize_t(ret);
9535}
9536#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009537
9538#ifdef HAVE_MKFIFO
9539/*[clinic input]
9540os.mkfifo
9541
9542 path: path_t
9543 mode: int=0o666
9544 *
9545 dir_fd: dir_fd(requires='mkfifoat')=None
9546
9547Create a "fifo" (a POSIX named pipe).
9548
9549If dir_fd is not None, it should be a file descriptor open to a directory,
9550 and path should be relative; path will then be relative to that directory.
9551dir_fd may not be implemented on your platform.
9552 If it is unavailable, using it will raise a NotImplementedError.
9553[clinic start generated code]*/
9554
Larry Hastings2f936352014-08-05 14:04:04 +10009555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009556os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9557/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009558{
9559 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009560 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009561
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009562 do {
9563 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009564#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009565 if (dir_fd != DEFAULT_DIR_FD)
9566 result = mkfifoat(dir_fd, path->narrow, mode);
9567 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009568#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009569 result = mkfifo(path->narrow, mode);
9570 Py_END_ALLOW_THREADS
9571 } while (result != 0 && errno == EINTR &&
9572 !(async_err = PyErr_CheckSignals()));
9573 if (result != 0)
9574 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009575
9576 Py_RETURN_NONE;
9577}
9578#endif /* HAVE_MKFIFO */
9579
9580
9581#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9582/*[clinic input]
9583os.mknod
9584
9585 path: path_t
9586 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009587 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009588 *
9589 dir_fd: dir_fd(requires='mknodat')=None
9590
9591Create a node in the file system.
9592
9593Create a node in the file system (file, device special file or named pipe)
9594at path. mode specifies both the permissions to use and the
9595type of node to be created, being combined (bitwise OR) with one of
9596S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9597device defines the newly created device special file (probably using
9598os.makedev()). Otherwise device is ignored.
9599
9600If dir_fd is not None, it should be a file descriptor open to a directory,
9601 and path should be relative; path will then be relative to that directory.
9602dir_fd may not be implemented on your platform.
9603 If it is unavailable, using it will raise a NotImplementedError.
9604[clinic start generated code]*/
9605
Larry Hastings2f936352014-08-05 14:04:04 +10009606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009607os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009608 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009609/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009610{
9611 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009612 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009613
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009614 do {
9615 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009616#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009617 if (dir_fd != DEFAULT_DIR_FD)
9618 result = mknodat(dir_fd, path->narrow, mode, device);
9619 else
Larry Hastings2f936352014-08-05 14:04:04 +10009620#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009621 result = mknod(path->narrow, mode, device);
9622 Py_END_ALLOW_THREADS
9623 } while (result != 0 && errno == EINTR &&
9624 !(async_err = PyErr_CheckSignals()));
9625 if (result != 0)
9626 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009627
9628 Py_RETURN_NONE;
9629}
9630#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9631
9632
9633#ifdef HAVE_DEVICE_MACROS
9634/*[clinic input]
9635os.major -> unsigned_int
9636
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009637 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009638 /
9639
9640Extracts a device major number from a raw device number.
9641[clinic start generated code]*/
9642
Larry Hastings2f936352014-08-05 14:04:04 +10009643static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009644os_major_impl(PyObject *module, dev_t device)
9645/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009646{
9647 return major(device);
9648}
9649
9650
9651/*[clinic input]
9652os.minor -> unsigned_int
9653
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009654 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009655 /
9656
9657Extracts a device minor number from a raw device number.
9658[clinic start generated code]*/
9659
Larry Hastings2f936352014-08-05 14:04:04 +10009660static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009661os_minor_impl(PyObject *module, dev_t device)
9662/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009663{
9664 return minor(device);
9665}
9666
9667
9668/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009669os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009670
9671 major: int
9672 minor: int
9673 /
9674
9675Composes a raw device number from the major and minor device numbers.
9676[clinic start generated code]*/
9677
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009678static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009679os_makedev_impl(PyObject *module, int major, int minor)
9680/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009681{
9682 return makedev(major, minor);
9683}
9684#endif /* HAVE_DEVICE_MACROS */
9685
9686
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009687#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009688/*[clinic input]
9689os.ftruncate
9690
9691 fd: int
9692 length: Py_off_t
9693 /
9694
9695Truncate a file, specified by file descriptor, to a specific length.
9696[clinic start generated code]*/
9697
Larry Hastings2f936352014-08-05 14:04:04 +10009698static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009699os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9700/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009701{
9702 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009703 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009704
Steve Dowerb82e17e2019-05-23 08:45:22 -07009705 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
9706 return NULL;
9707 }
9708
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009709 do {
9710 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009711 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009712#ifdef MS_WINDOWS
9713 result = _chsize_s(fd, length);
9714#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009715 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009716#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009717 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009718 Py_END_ALLOW_THREADS
9719 } while (result != 0 && errno == EINTR &&
9720 !(async_err = PyErr_CheckSignals()));
9721 if (result != 0)
9722 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009723 Py_RETURN_NONE;
9724}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009725#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009726
9727
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009728#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009729/*[clinic input]
9730os.truncate
9731 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9732 length: Py_off_t
9733
9734Truncate a file, specified by path, to a specific length.
9735
9736On some platforms, path may also be specified as an open file descriptor.
9737 If this functionality is unavailable, using it raises an exception.
9738[clinic start generated code]*/
9739
Larry Hastings2f936352014-08-05 14:04:04 +10009740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009741os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9742/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009743{
9744 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009745#ifdef MS_WINDOWS
9746 int fd;
9747#endif
9748
9749 if (path->fd != -1)
9750 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009751
Steve Dowerb82e17e2019-05-23 08:45:22 -07009752 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
9753 return NULL;
9754 }
9755
Larry Hastings2f936352014-08-05 14:04:04 +10009756 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009757 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009758#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009759 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009760 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009761 result = -1;
9762 else {
9763 result = _chsize_s(fd, length);
9764 close(fd);
9765 if (result < 0)
9766 errno = result;
9767 }
9768#else
9769 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009770#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009771 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009772 Py_END_ALLOW_THREADS
9773 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009774 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009775
9776 Py_RETURN_NONE;
9777}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009778#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009779
Ross Lagerwall7807c352011-03-17 20:20:30 +02009780
Victor Stinnerd6b17692014-09-30 12:20:05 +02009781/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9782 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9783 defined, which is the case in Python on AIX. AIX bug report:
9784 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9785#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9786# define POSIX_FADVISE_AIX_BUG
9787#endif
9788
Victor Stinnerec39e262014-09-30 12:35:58 +02009789
Victor Stinnerd6b17692014-09-30 12:20:05 +02009790#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009791/*[clinic input]
9792os.posix_fallocate
9793
9794 fd: int
9795 offset: Py_off_t
9796 length: Py_off_t
9797 /
9798
9799Ensure a file has allocated at least a particular number of bytes on disk.
9800
9801Ensure that the file specified by fd encompasses a range of bytes
9802starting at offset bytes from the beginning and continuing for length bytes.
9803[clinic start generated code]*/
9804
Larry Hastings2f936352014-08-05 14:04:04 +10009805static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009806os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009807 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009808/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009809{
9810 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009811 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009812
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009813 do {
9814 Py_BEGIN_ALLOW_THREADS
9815 result = posix_fallocate(fd, offset, length);
9816 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009817 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9818
9819 if (result == 0)
9820 Py_RETURN_NONE;
9821
9822 if (async_err)
9823 return NULL;
9824
9825 errno = result;
9826 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009827}
Victor Stinnerec39e262014-09-30 12:35:58 +02009828#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009829
Ross Lagerwall7807c352011-03-17 20:20:30 +02009830
Victor Stinnerd6b17692014-09-30 12:20:05 +02009831#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009832/*[clinic input]
9833os.posix_fadvise
9834
9835 fd: int
9836 offset: Py_off_t
9837 length: Py_off_t
9838 advice: int
9839 /
9840
9841Announce an intention to access data in a specific pattern.
9842
9843Announce an intention to access data in a specific pattern, thus allowing
9844the kernel to make optimizations.
9845The advice applies to the region of the file specified by fd starting at
9846offset and continuing for length bytes.
9847advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9848POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9849POSIX_FADV_DONTNEED.
9850[clinic start generated code]*/
9851
Larry Hastings2f936352014-08-05 14:04:04 +10009852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009853os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009854 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009855/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009856{
9857 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009858 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009859
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009860 do {
9861 Py_BEGIN_ALLOW_THREADS
9862 result = posix_fadvise(fd, offset, length, advice);
9863 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009864 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9865
9866 if (result == 0)
9867 Py_RETURN_NONE;
9868
9869 if (async_err)
9870 return NULL;
9871
9872 errno = result;
9873 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009874}
Victor Stinnerec39e262014-09-30 12:35:58 +02009875#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009876
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009877#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009878
Fred Drake762e2061999-08-26 17:23:54 +00009879/* Save putenv() parameters as values here, so we can collect them when they
9880 * get re-set with another call for the same key. */
9881static PyObject *posix_putenv_garbage;
9882
Larry Hastings2f936352014-08-05 14:04:04 +10009883static void
9884posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009885{
Larry Hastings2f936352014-08-05 14:04:04 +10009886 /* Install the first arg and newstr in posix_putenv_garbage;
9887 * this will cause previous value to be collected. This has to
9888 * happen after the real putenv() call because the old value
9889 * was still accessible until then. */
9890 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9891 /* really not much we can do; just leak */
9892 PyErr_Clear();
9893 else
9894 Py_DECREF(value);
9895}
9896
9897
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009898#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009899/*[clinic input]
9900os.putenv
9901
9902 name: unicode
9903 value: unicode
9904 /
9905
9906Change or add an environment variable.
9907[clinic start generated code]*/
9908
Larry Hastings2f936352014-08-05 14:04:04 +10009909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009910os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9911/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009912{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009913 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009914 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009915
Serhiy Storchaka77703942017-06-25 07:33:01 +03009916 /* Search from index 1 because on Windows starting '=' is allowed for
9917 defining hidden environment variables. */
9918 if (PyUnicode_GET_LENGTH(name) == 0 ||
9919 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9920 {
9921 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9922 return NULL;
9923 }
Larry Hastings2f936352014-08-05 14:04:04 +10009924 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9925 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009926 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009927 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009928
9929 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9930 if (env == NULL)
9931 goto error;
9932 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009933 PyErr_Format(PyExc_ValueError,
9934 "the environment variable is longer than %u characters",
9935 _MAX_ENV);
9936 goto error;
9937 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009938 if (wcslen(env) != (size_t)size) {
9939 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009940 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009941 }
9942
Larry Hastings2f936352014-08-05 14:04:04 +10009943 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009945 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009947
Larry Hastings2f936352014-08-05 14:04:04 +10009948 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009949 Py_RETURN_NONE;
9950
9951error:
Larry Hastings2f936352014-08-05 14:04:04 +10009952 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009953 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009954}
Larry Hastings2f936352014-08-05 14:04:04 +10009955#else /* MS_WINDOWS */
9956/*[clinic input]
9957os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009958
Larry Hastings2f936352014-08-05 14:04:04 +10009959 name: FSConverter
9960 value: FSConverter
9961 /
9962
9963Change or add an environment variable.
9964[clinic start generated code]*/
9965
Larry Hastings2f936352014-08-05 14:04:04 +10009966static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009967os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9968/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009969{
9970 PyObject *bytes = NULL;
9971 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009972 const char *name_string = PyBytes_AS_STRING(name);
9973 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009974
Serhiy Storchaka77703942017-06-25 07:33:01 +03009975 if (strchr(name_string, '=') != NULL) {
9976 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9977 return NULL;
9978 }
Larry Hastings2f936352014-08-05 14:04:04 +10009979 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9980 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009981 return NULL;
9982 }
9983
9984 env = PyBytes_AS_STRING(bytes);
9985 if (putenv(env)) {
9986 Py_DECREF(bytes);
9987 return posix_error();
9988 }
9989
9990 posix_putenv_garbage_setitem(name, bytes);
9991 Py_RETURN_NONE;
9992}
9993#endif /* MS_WINDOWS */
9994#endif /* HAVE_PUTENV */
9995
9996
9997#ifdef HAVE_UNSETENV
9998/*[clinic input]
9999os.unsetenv
10000 name: FSConverter
10001 /
10002
10003Delete an environment variable.
10004[clinic start generated code]*/
10005
Larry Hastings2f936352014-08-05 14:04:04 +100010006static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010007os_unsetenv_impl(PyObject *module, PyObject *name)
10008/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010009{
Victor Stinner984890f2011-11-24 13:53:38 +010010010#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010010011 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010010012#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000010013
Victor Stinner984890f2011-11-24 13:53:38 +010010014#ifdef HAVE_BROKEN_UNSETENV
10015 unsetenv(PyBytes_AS_STRING(name));
10016#else
Victor Stinner65170952011-11-22 22:16:17 +010010017 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100010018 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010010019 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010010020#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010021
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 /* Remove the key from posix_putenv_garbage;
10023 * this will cause it to be collected. This has to
10024 * happen after the real unsetenv() call because the
10025 * old value was still accessible until then.
10026 */
Victor Stinner65170952011-11-22 22:16:17 +010010027 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020010029 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
10030 return NULL;
10031 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 PyErr_Clear();
10033 }
Victor Stinner84ae1182010-05-06 22:05:07 +000010034 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010035}
Larry Hastings2f936352014-08-05 14:04:04 +100010036#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000010037
Larry Hastings2f936352014-08-05 14:04:04 +100010038
10039/*[clinic input]
10040os.strerror
10041
10042 code: int
10043 /
10044
10045Translate an error code to a message string.
10046[clinic start generated code]*/
10047
Larry Hastings2f936352014-08-05 14:04:04 +100010048static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010049os_strerror_impl(PyObject *module, int code)
10050/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010051{
10052 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 if (message == NULL) {
10054 PyErr_SetString(PyExc_ValueError,
10055 "strerror() argument out of range");
10056 return NULL;
10057 }
Victor Stinner1b579672011-12-17 05:47:23 +010010058 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010059}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010060
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010061
Guido van Rossumc9641791998-08-04 15:26:23 +000010062#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010063#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010064/*[clinic input]
10065os.WCOREDUMP -> bool
10066
10067 status: int
10068 /
10069
10070Return True if the process returning status was dumped to a core file.
10071[clinic start generated code]*/
10072
Larry Hastings2f936352014-08-05 14:04:04 +100010073static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010074os_WCOREDUMP_impl(PyObject *module, int status)
10075/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010076{
10077 WAIT_TYPE wait_status;
10078 WAIT_STATUS_INT(wait_status) = status;
10079 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010080}
10081#endif /* WCOREDUMP */
10082
Larry Hastings2f936352014-08-05 14:04:04 +100010083
Fred Drake106c1a02002-04-23 15:58:02 +000010084#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010085/*[clinic input]
10086os.WIFCONTINUED -> bool
10087
10088 status: int
10089
10090Return True if a particular process was continued from a job control stop.
10091
10092Return True if the process returning status was continued from a
10093job control stop.
10094[clinic start generated code]*/
10095
Larry Hastings2f936352014-08-05 14:04:04 +100010096static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010097os_WIFCONTINUED_impl(PyObject *module, int status)
10098/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010099{
10100 WAIT_TYPE wait_status;
10101 WAIT_STATUS_INT(wait_status) = status;
10102 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010103}
10104#endif /* WIFCONTINUED */
10105
Larry Hastings2f936352014-08-05 14:04:04 +100010106
Guido van Rossumc9641791998-08-04 15:26:23 +000010107#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010108/*[clinic input]
10109os.WIFSTOPPED -> bool
10110
10111 status: int
10112
10113Return True if the process returning status was stopped.
10114[clinic start generated code]*/
10115
Larry Hastings2f936352014-08-05 14:04:04 +100010116static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010117os_WIFSTOPPED_impl(PyObject *module, int status)
10118/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010119{
10120 WAIT_TYPE wait_status;
10121 WAIT_STATUS_INT(wait_status) = status;
10122 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010123}
10124#endif /* WIFSTOPPED */
10125
Larry Hastings2f936352014-08-05 14:04:04 +100010126
Guido van Rossumc9641791998-08-04 15:26:23 +000010127#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010128/*[clinic input]
10129os.WIFSIGNALED -> bool
10130
10131 status: int
10132
10133Return True if the process returning status was terminated by a signal.
10134[clinic start generated code]*/
10135
Larry Hastings2f936352014-08-05 14:04:04 +100010136static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010137os_WIFSIGNALED_impl(PyObject *module, int status)
10138/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010139{
10140 WAIT_TYPE wait_status;
10141 WAIT_STATUS_INT(wait_status) = status;
10142 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010143}
10144#endif /* WIFSIGNALED */
10145
Larry Hastings2f936352014-08-05 14:04:04 +100010146
Guido van Rossumc9641791998-08-04 15:26:23 +000010147#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010148/*[clinic input]
10149os.WIFEXITED -> bool
10150
10151 status: int
10152
10153Return True if the process returning status exited via the exit() system call.
10154[clinic start generated code]*/
10155
Larry Hastings2f936352014-08-05 14:04:04 +100010156static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010157os_WIFEXITED_impl(PyObject *module, int status)
10158/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010159{
10160 WAIT_TYPE wait_status;
10161 WAIT_STATUS_INT(wait_status) = status;
10162 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010163}
10164#endif /* WIFEXITED */
10165
Larry Hastings2f936352014-08-05 14:04:04 +100010166
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010167#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010168/*[clinic input]
10169os.WEXITSTATUS -> int
10170
10171 status: int
10172
10173Return the process return code from status.
10174[clinic start generated code]*/
10175
Larry Hastings2f936352014-08-05 14:04:04 +100010176static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010177os_WEXITSTATUS_impl(PyObject *module, int status)
10178/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010179{
10180 WAIT_TYPE wait_status;
10181 WAIT_STATUS_INT(wait_status) = status;
10182 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010183}
10184#endif /* WEXITSTATUS */
10185
Larry Hastings2f936352014-08-05 14:04:04 +100010186
Guido van Rossumc9641791998-08-04 15:26:23 +000010187#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010188/*[clinic input]
10189os.WTERMSIG -> int
10190
10191 status: int
10192
10193Return the signal that terminated the process that provided the status value.
10194[clinic start generated code]*/
10195
Larry Hastings2f936352014-08-05 14:04:04 +100010196static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010197os_WTERMSIG_impl(PyObject *module, int status)
10198/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010199{
10200 WAIT_TYPE wait_status;
10201 WAIT_STATUS_INT(wait_status) = status;
10202 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010203}
10204#endif /* WTERMSIG */
10205
Larry Hastings2f936352014-08-05 14:04:04 +100010206
Guido van Rossumc9641791998-08-04 15:26:23 +000010207#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010208/*[clinic input]
10209os.WSTOPSIG -> int
10210
10211 status: int
10212
10213Return the signal that stopped the process that provided the status value.
10214[clinic start generated code]*/
10215
Larry Hastings2f936352014-08-05 14:04:04 +100010216static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010217os_WSTOPSIG_impl(PyObject *module, int status)
10218/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010219{
10220 WAIT_TYPE wait_status;
10221 WAIT_STATUS_INT(wait_status) = status;
10222 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010223}
10224#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010225#endif /* HAVE_SYS_WAIT_H */
10226
10227
Thomas Wouters477c8d52006-05-27 19:21:47 +000010228#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010229#ifdef _SCO_DS
10230/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10231 needed definitions in sys/statvfs.h */
10232#define _SVID3
10233#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010234#include <sys/statvfs.h>
10235
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010236static PyObject*
10237_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010238 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 if (v == NULL)
10240 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010241
10242#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10244 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10245 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10246 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10247 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10248 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10249 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10250 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10251 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10252 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010253#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10255 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10256 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010257 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010259 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010261 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010263 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010265 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010267 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10269 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010270#endif
Michael Felt502d5512018-01-05 13:01:58 +010010271/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10272 * (issue #32390). */
10273#if defined(_AIX) && defined(_ALL_SOURCE)
10274 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10275#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010276 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010277#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010278 if (PyErr_Occurred()) {
10279 Py_DECREF(v);
10280 return NULL;
10281 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010282
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010284}
10285
Larry Hastings2f936352014-08-05 14:04:04 +100010286
10287/*[clinic input]
10288os.fstatvfs
10289 fd: int
10290 /
10291
10292Perform an fstatvfs system call on the given fd.
10293
10294Equivalent to statvfs(fd).
10295[clinic start generated code]*/
10296
Larry Hastings2f936352014-08-05 14:04:04 +100010297static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010298os_fstatvfs_impl(PyObject *module, int fd)
10299/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010300{
10301 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010302 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010304
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010305 do {
10306 Py_BEGIN_ALLOW_THREADS
10307 result = fstatvfs(fd, &st);
10308 Py_END_ALLOW_THREADS
10309 } while (result != 0 && errno == EINTR &&
10310 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010311 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010312 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010313
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010315}
Larry Hastings2f936352014-08-05 14:04:04 +100010316#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010317
10318
Thomas Wouters477c8d52006-05-27 19:21:47 +000010319#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010320#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010321/*[clinic input]
10322os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010323
Larry Hastings2f936352014-08-05 14:04:04 +100010324 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10325
10326Perform a statvfs system call on the given path.
10327
10328path may always be specified as a string.
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 PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010334os_statvfs_impl(PyObject *module, path_t *path)
10335/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010336{
10337 int result;
10338 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010339
10340 Py_BEGIN_ALLOW_THREADS
10341#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010342 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010343#ifdef __APPLE__
10344 /* handle weak-linking on Mac OS X 10.3 */
10345 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010346 fd_specified("statvfs", path->fd);
10347 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010348 }
10349#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010350 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010351 }
10352 else
10353#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010354 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010355 Py_END_ALLOW_THREADS
10356
10357 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010358 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010359 }
10360
Larry Hastings2f936352014-08-05 14:04:04 +100010361 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010362}
Larry Hastings2f936352014-08-05 14:04:04 +100010363#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10364
Guido van Rossum94f6f721999-01-06 18:42:14 +000010365
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010366#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010367/*[clinic input]
10368os._getdiskusage
10369
Steve Dower23ad6d02018-02-22 10:39:10 -080010370 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010371
10372Return disk usage statistics about the given path as a (total, free) tuple.
10373[clinic start generated code]*/
10374
Larry Hastings2f936352014-08-05 14:04:04 +100010375static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010376os__getdiskusage_impl(PyObject *module, path_t *path)
10377/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010378{
10379 BOOL retval;
10380 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010381 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010382
10383 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010384 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010385 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010386 if (retval == 0) {
10387 if (GetLastError() == ERROR_DIRECTORY) {
10388 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010389
Joe Pamerc8c02492018-09-25 10:57:36 -040010390 dir_path = PyMem_New(wchar_t, path->length + 1);
10391 if (dir_path == NULL) {
10392 return PyErr_NoMemory();
10393 }
10394
10395 wcscpy_s(dir_path, path->length + 1, path->wide);
10396
10397 if (_dirnameW(dir_path) != -1) {
10398 Py_BEGIN_ALLOW_THREADS
10399 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10400 Py_END_ALLOW_THREADS
10401 }
10402 /* Record the last error in case it's modified by PyMem_Free. */
10403 err = GetLastError();
10404 PyMem_Free(dir_path);
10405 if (retval) {
10406 goto success;
10407 }
10408 }
10409 return PyErr_SetFromWindowsErr(err);
10410 }
10411
10412success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010413 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10414}
Larry Hastings2f936352014-08-05 14:04:04 +100010415#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010416
10417
Fred Drakec9680921999-12-13 16:37:25 +000010418/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10419 * It maps strings representing configuration variable names to
10420 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010421 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010422 * rarely-used constants. There are three separate tables that use
10423 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010424 *
10425 * This code is always included, even if none of the interfaces that
10426 * need it are included. The #if hackery needed to avoid it would be
10427 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010428 */
10429struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010430 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010431 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010432};
10433
Fred Drake12c6e2d1999-12-14 21:25:03 +000010434static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010435conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010436 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010437{
Christian Heimes217cfd12007-12-02 14:31:20 +000010438 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010439 int value = _PyLong_AsInt(arg);
10440 if (value == -1 && PyErr_Occurred())
10441 return 0;
10442 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010443 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010444 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010445 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010446 /* look up the value in the table using a binary search */
10447 size_t lo = 0;
10448 size_t mid;
10449 size_t hi = tablesize;
10450 int cmp;
10451 const char *confname;
10452 if (!PyUnicode_Check(arg)) {
10453 PyErr_SetString(PyExc_TypeError,
10454 "configuration names must be strings or integers");
10455 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010457 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010458 if (confname == NULL)
10459 return 0;
10460 while (lo < hi) {
10461 mid = (lo + hi) / 2;
10462 cmp = strcmp(confname, table[mid].name);
10463 if (cmp < 0)
10464 hi = mid;
10465 else if (cmp > 0)
10466 lo = mid + 1;
10467 else {
10468 *valuep = table[mid].value;
10469 return 1;
10470 }
10471 }
10472 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10473 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010475}
10476
10477
10478#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10479static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010480#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010482#endif
10483#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010485#endif
Fred Drakec9680921999-12-13 16:37:25 +000010486#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
10501#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010503#endif
10504#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
10507#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010509#endif
10510#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010512#endif
10513#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010515#endif
10516#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010531#ifdef _PC_ACL_ENABLED
10532 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10533#endif
10534#ifdef _PC_MIN_HOLE_SIZE
10535 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10536#endif
10537#ifdef _PC_ALLOC_SIZE_MIN
10538 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10539#endif
10540#ifdef _PC_REC_INCR_XFER_SIZE
10541 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10542#endif
10543#ifdef _PC_REC_MAX_XFER_SIZE
10544 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10545#endif
10546#ifdef _PC_REC_MIN_XFER_SIZE
10547 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10548#endif
10549#ifdef _PC_REC_XFER_ALIGN
10550 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10551#endif
10552#ifdef _PC_SYMLINK_MAX
10553 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10554#endif
10555#ifdef _PC_XATTR_ENABLED
10556 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10557#endif
10558#ifdef _PC_XATTR_EXISTS
10559 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10560#endif
10561#ifdef _PC_TIMESTAMP_RESOLUTION
10562 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10563#endif
Fred Drakec9680921999-12-13 16:37:25 +000010564};
10565
Fred Drakec9680921999-12-13 16:37:25 +000010566static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010567conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010568{
10569 return conv_confname(arg, valuep, posix_constants_pathconf,
10570 sizeof(posix_constants_pathconf)
10571 / sizeof(struct constdef));
10572}
10573#endif
10574
Larry Hastings2f936352014-08-05 14:04:04 +100010575
Fred Drakec9680921999-12-13 16:37:25 +000010576#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010577/*[clinic input]
10578os.fpathconf -> long
10579
10580 fd: int
10581 name: path_confname
10582 /
10583
10584Return the configuration limit name for the file descriptor fd.
10585
10586If there is no limit, return -1.
10587[clinic start generated code]*/
10588
Larry Hastings2f936352014-08-05 14:04:04 +100010589static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010590os_fpathconf_impl(PyObject *module, int fd, int name)
10591/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010592{
10593 long limit;
10594
10595 errno = 0;
10596 limit = fpathconf(fd, name);
10597 if (limit == -1 && errno != 0)
10598 posix_error();
10599
10600 return limit;
10601}
10602#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010603
10604
10605#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010606/*[clinic input]
10607os.pathconf -> long
10608 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10609 name: path_confname
10610
10611Return the configuration limit name for the file or directory path.
10612
10613If there is no limit, return -1.
10614On some platforms, path may also be specified as an open file descriptor.
10615 If this functionality is unavailable, using it raises an exception.
10616[clinic start generated code]*/
10617
Larry Hastings2f936352014-08-05 14:04:04 +100010618static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010619os_pathconf_impl(PyObject *module, path_t *path, int name)
10620/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010621{
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010623
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010625#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010626 if (path->fd != -1)
10627 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010628 else
10629#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010630 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 if (limit == -1 && errno != 0) {
10632 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010633 /* could be a path or name problem */
10634 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010635 else
Larry Hastings2f936352014-08-05 14:04:04 +100010636 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 }
Larry Hastings2f936352014-08-05 14:04:04 +100010638
10639 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010640}
Larry Hastings2f936352014-08-05 14:04:04 +100010641#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010642
10643#ifdef HAVE_CONFSTR
10644static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010645#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010647#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010648#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010650#endif
10651#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010653#endif
Fred Draked86ed291999-12-15 15:34:33 +000010654#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010655 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010656#endif
10657#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010658 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010659#endif
10660#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010661 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010662#endif
10663#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010665#endif
Fred Drakec9680921999-12-13 16:37:25 +000010666#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010668#endif
10669#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010671#endif
10672#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010674#endif
10675#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010677#endif
10678#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010680#endif
10681#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010683#endif
10684#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010686#endif
10687#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010689#endif
Fred Draked86ed291999-12-15 15:34:33 +000010690#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010692#endif
Fred Drakec9680921999-12-13 16:37:25 +000010693#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010695#endif
Fred Draked86ed291999-12-15 15:34:33 +000010696#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010698#endif
10699#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010701#endif
10702#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010704#endif
10705#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010707#endif
Fred Drakec9680921999-12-13 16:37:25 +000010708#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010710#endif
10711#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010713#endif
10714#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010716#endif
10717#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010719#endif
10720#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010722#endif
10723#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010725#endif
10726#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010728#endif
10729#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010731#endif
10732#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010734#endif
10735#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010737#endif
10738#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010740#endif
10741#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010743#endif
10744#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010746#endif
10747#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010749#endif
10750#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010752#endif
10753#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010755#endif
Fred Draked86ed291999-12-15 15:34:33 +000010756#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010758#endif
10759#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010761#endif
10762#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010764#endif
10765#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010767#endif
10768#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010770#endif
10771#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010773#endif
10774#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010776#endif
10777#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010779#endif
10780#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010782#endif
10783#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010785#endif
10786#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010788#endif
10789#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010791#endif
10792#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010794#endif
Fred Drakec9680921999-12-13 16:37:25 +000010795};
10796
10797static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010798conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010799{
10800 return conv_confname(arg, valuep, posix_constants_confstr,
10801 sizeof(posix_constants_confstr)
10802 / sizeof(struct constdef));
10803}
10804
Larry Hastings2f936352014-08-05 14:04:04 +100010805
10806/*[clinic input]
10807os.confstr
10808
10809 name: confstr_confname
10810 /
10811
10812Return a string-valued system configuration variable.
10813[clinic start generated code]*/
10814
Larry Hastings2f936352014-08-05 14:04:04 +100010815static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010816os_confstr_impl(PyObject *module, int name)
10817/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010818{
10819 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010820 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010821 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010822
Victor Stinnercb043522010-09-10 23:49:04 +000010823 errno = 0;
10824 len = confstr(name, buffer, sizeof(buffer));
10825 if (len == 0) {
10826 if (errno) {
10827 posix_error();
10828 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010829 }
10830 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010831 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010832 }
10833 }
Victor Stinnercb043522010-09-10 23:49:04 +000010834
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010835 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010836 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010837 char *buf = PyMem_Malloc(len);
10838 if (buf == NULL)
10839 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010840 len2 = confstr(name, buf, len);
10841 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010842 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010843 PyMem_Free(buf);
10844 }
10845 else
10846 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010847 return result;
10848}
Larry Hastings2f936352014-08-05 14:04:04 +100010849#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010850
10851
10852#ifdef HAVE_SYSCONF
10853static struct constdef posix_constants_sysconf[] = {
10854#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010856#endif
10857#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010859#endif
10860#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010862#endif
10863#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010865#endif
10866#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010868#endif
10869#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010871#endif
10872#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010874#endif
10875#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010877#endif
10878#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010880#endif
10881#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010883#endif
Fred Draked86ed291999-12-15 15:34:33 +000010884#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010886#endif
10887#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010889#endif
Fred Drakec9680921999-12-13 16:37:25 +000010890#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
Fred Drakec9680921999-12-13 16:37:25 +000010893#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
Fred Draked86ed291999-12-15 15:34:33 +000010908#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010910#endif
Fred Drakec9680921999-12-13 16:37:25 +000010911#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010913#endif
10914#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010916#endif
10917#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010919#endif
10920#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010922#endif
10923#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010925#endif
Fred Draked86ed291999-12-15 15:34:33 +000010926#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010928#endif
Fred Drakec9680921999-12-13 16:37:25 +000010929#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010931#endif
10932#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010934#endif
10935#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
10938#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010940#endif
10941#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010943#endif
10944#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010946#endif
10947#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010949#endif
10950#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010952#endif
10953#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010955#endif
10956#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010958#endif
10959#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010961#endif
10962#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010964#endif
10965#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
10968#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010970#endif
10971#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010973#endif
10974#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010976#endif
10977#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010979#endif
10980#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010982#endif
10983#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010985#endif
10986#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010988#endif
10989#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010991#endif
10992#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010994#endif
10995#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010997#endif
Fred Draked86ed291999-12-15 15:34:33 +000010998#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011000#endif
Fred Drakec9680921999-12-13 16:37:25 +000011001#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011003#endif
11004#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011006#endif
11007#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011009#endif
Fred Draked86ed291999-12-15 15:34:33 +000011010#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011012#endif
Fred Drakec9680921999-12-13 16:37:25 +000011013#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011015#endif
Fred Draked86ed291999-12-15 15:34:33 +000011016#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011018#endif
11019#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011021#endif
Fred Drakec9680921999-12-13 16:37:25 +000011022#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011024#endif
11025#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011027#endif
11028#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011030#endif
11031#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011033#endif
Fred Draked86ed291999-12-15 15:34:33 +000011034#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011036#endif
Fred Drakec9680921999-12-13 16:37:25 +000011037#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011039#endif
11040#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011042#endif
11043#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011045#endif
11046#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011048#endif
11049#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011051#endif
11052#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011054#endif
11055#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011057#endif
Fred Draked86ed291999-12-15 15:34:33 +000011058#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011060#endif
Fred Drakec9680921999-12-13 16:37:25 +000011061#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011063#endif
11064#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011066#endif
Fred Draked86ed291999-12-15 15:34:33 +000011067#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011069#endif
Fred Drakec9680921999-12-13 16:37:25 +000011070#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011072#endif
11073#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011075#endif
11076#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011078#endif
11079#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011081#endif
11082#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011084#endif
11085#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011087#endif
11088#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011090#endif
11091#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011093#endif
11094#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011096#endif
Fred Draked86ed291999-12-15 15:34:33 +000011097#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011099#endif
11100#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011102#endif
Fred Drakec9680921999-12-13 16:37:25 +000011103#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
11106#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
11121#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
11124#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011126#endif
11127#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011129#endif
11130#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011132#endif
11133#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011135#endif
11136#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011138#endif
11139#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011141#endif
11142#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011144#endif
11145#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011147#endif
11148#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011150#endif
11151#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011153#endif
11154#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011156#endif
11157#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011159#endif
11160#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011162#endif
11163#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011165#endif
11166#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011168#endif
11169#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011171#endif
11172#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011174#endif
11175#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011177#endif
11178#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011180#endif
11181#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011183#endif
11184#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011186#endif
11187#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011189#endif
11190#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011192#endif
11193#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011194 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011195#endif
11196#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011197 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011198#endif
11199#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011200 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011201#endif
11202#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011204#endif
11205#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011207#endif
Fred Draked86ed291999-12-15 15:34:33 +000011208#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011210#endif
Fred Drakec9680921999-12-13 16:37:25 +000011211#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011213#endif
11214#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011216#endif
11217#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011219#endif
11220#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011222#endif
11223#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011225#endif
11226#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011228#endif
11229#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011231#endif
11232#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011234#endif
11235#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011237#endif
11238#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011240#endif
11241#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011243#endif
11244#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011246#endif
11247#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011249#endif
11250#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011252#endif
11253#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011255#endif
11256#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011258#endif
11259#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011261#endif
11262#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011263 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011264#endif
11265#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011267#endif
11268#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011270#endif
11271#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011272 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011273#endif
11274#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011275 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011276#endif
11277#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011279#endif
11280#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011281 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011282#endif
11283#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011285#endif
11286#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011288#endif
11289#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011291#endif
11292#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011294#endif
11295#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011297#endif
11298#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011300#endif
11301#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011303#endif
11304#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011306#endif
11307#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011309#endif
11310#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011312#endif
11313#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011315#endif
11316#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011317 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011318#endif
11319#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011320 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011321#endif
11322#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011324#endif
11325#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011327#endif
11328#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011330#endif
11331#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011333#endif
11334#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011336#endif
11337#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011339#endif
11340#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011342#endif
11343#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011345#endif
11346};
11347
11348static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011349conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011350{
11351 return conv_confname(arg, valuep, posix_constants_sysconf,
11352 sizeof(posix_constants_sysconf)
11353 / sizeof(struct constdef));
11354}
11355
Larry Hastings2f936352014-08-05 14:04:04 +100011356
11357/*[clinic input]
11358os.sysconf -> long
11359 name: sysconf_confname
11360 /
11361
11362Return an integer-valued system configuration variable.
11363[clinic start generated code]*/
11364
Larry Hastings2f936352014-08-05 14:04:04 +100011365static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011366os_sysconf_impl(PyObject *module, int name)
11367/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011368{
11369 long value;
11370
11371 errno = 0;
11372 value = sysconf(name);
11373 if (value == -1 && errno != 0)
11374 posix_error();
11375 return value;
11376}
11377#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011378
11379
Fred Drakebec628d1999-12-15 18:31:10 +000011380/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011381 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011382 * the exported dictionaries that are used to publish information about the
11383 * names available on the host platform.
11384 *
11385 * Sorting the table at runtime ensures that the table is properly ordered
11386 * when used, even for platforms we're not able to test on. It also makes
11387 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011388 */
Fred Drakebec628d1999-12-15 18:31:10 +000011389
11390static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011391cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011392{
11393 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011395 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011397
11398 return strcmp(c1->name, c2->name);
11399}
11400
11401static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011402setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011403 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011404{
Fred Drakebec628d1999-12-15 18:31:10 +000011405 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011406 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011407
11408 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11409 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011410 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011412
Barry Warsaw3155db32000-04-13 15:20:40 +000011413 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 PyObject *o = PyLong_FromLong(table[i].value);
11415 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11416 Py_XDECREF(o);
11417 Py_DECREF(d);
11418 return -1;
11419 }
11420 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011421 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011422 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011423}
11424
Fred Drakebec628d1999-12-15 18:31:10 +000011425/* Return -1 on failure, 0 on success. */
11426static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011427setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011428{
11429#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011430 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011431 sizeof(posix_constants_pathconf)
11432 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011433 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011434 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011435#endif
11436#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011437 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011438 sizeof(posix_constants_confstr)
11439 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011440 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011441 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011442#endif
11443#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011444 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011445 sizeof(posix_constants_sysconf)
11446 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011447 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011448 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011449#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011450 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011451}
Fred Draked86ed291999-12-15 15:34:33 +000011452
11453
Larry Hastings2f936352014-08-05 14:04:04 +100011454/*[clinic input]
11455os.abort
11456
11457Abort the interpreter immediately.
11458
11459This function 'dumps core' or otherwise fails in the hardest way possible
11460on the hosting operating system. This function never returns.
11461[clinic start generated code]*/
11462
Larry Hastings2f936352014-08-05 14:04:04 +100011463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011464os_abort_impl(PyObject *module)
11465/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011466{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011467 abort();
11468 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011469#ifndef __clang__
11470 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11471 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11472 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011473 Py_FatalError("abort() called from Python code didn't abort!");
11474 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011475#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011476}
Fred Drakebec628d1999-12-15 18:31:10 +000011477
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011478#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011479/* Grab ShellExecute dynamically from shell32 */
11480static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011481static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11482 LPCWSTR, INT);
11483static int
11484check_ShellExecute()
11485{
11486 HINSTANCE hShell32;
11487
11488 /* only recheck */
11489 if (-1 == has_ShellExecute) {
11490 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011491 /* Security note: this call is not vulnerable to "DLL hijacking".
11492 SHELL32 is part of "KnownDLLs" and so Windows always load
11493 the system SHELL32.DLL, even if there is another SHELL32.DLL
11494 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011495 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011496 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011497 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11498 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011499 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011500 } else {
11501 has_ShellExecute = 0;
11502 }
Tony Roberts4860f012019-02-02 18:16:42 +010011503 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011504 }
11505 return has_ShellExecute;
11506}
11507
11508
Steve Dowercc16be82016-09-08 10:35:16 -070011509/*[clinic input]
11510os.startfile
11511 filepath: path_t
11512 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011513
Steve Dowercc16be82016-09-08 10:35:16 -070011514startfile(filepath [, operation])
11515
11516Start a file with its associated application.
11517
11518When "operation" is not specified or "open", this acts like
11519double-clicking the file in Explorer, or giving the file name as an
11520argument to the DOS "start" command: the file is opened with whatever
11521application (if any) its extension is associated.
11522When another "operation" is given, it specifies what should be done with
11523the file. A typical operation is "print".
11524
11525startfile returns as soon as the associated application is launched.
11526There is no option to wait for the application to close, and no way
11527to retrieve the application's exit status.
11528
11529The filepath is relative to the current directory. If you want to use
11530an absolute path, make sure the first character is not a slash ("/");
11531the underlying Win32 ShellExecute function doesn't work if it is.
11532[clinic start generated code]*/
11533
11534static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011535os_startfile_impl(PyObject *module, path_t *filepath,
11536 const Py_UNICODE *operation)
11537/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011538{
11539 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011540
11541 if(!check_ShellExecute()) {
11542 /* If the OS doesn't have ShellExecute, return a
11543 NotImplementedError. */
11544 return PyErr_Format(PyExc_NotImplementedError,
11545 "startfile not available on this platform");
11546 }
11547
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011549 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011550 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 Py_END_ALLOW_THREADS
11552
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011554 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011555 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 }
Steve Dowercc16be82016-09-08 10:35:16 -070011557 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011558}
Larry Hastings2f936352014-08-05 14:04:04 +100011559#endif /* MS_WINDOWS */
11560
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011561
Martin v. Löwis438b5342002-12-27 10:16:42 +000011562#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011563/*[clinic input]
11564os.getloadavg
11565
11566Return average recent system load information.
11567
11568Return the number of processes in the system run queue averaged over
11569the last 1, 5, and 15 minutes as a tuple of three floats.
11570Raises OSError if the load average was unobtainable.
11571[clinic start generated code]*/
11572
Larry Hastings2f936352014-08-05 14:04:04 +100011573static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011574os_getloadavg_impl(PyObject *module)
11575/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011576{
11577 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011578 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011579 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11580 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011581 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011582 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011583}
Larry Hastings2f936352014-08-05 14:04:04 +100011584#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011585
Larry Hastings2f936352014-08-05 14:04:04 +100011586
11587/*[clinic input]
11588os.device_encoding
11589 fd: int
11590
11591Return a string describing the encoding of a terminal's file descriptor.
11592
11593The file descriptor must be attached to a terminal.
11594If the device is not a terminal, return None.
11595[clinic start generated code]*/
11596
Larry Hastings2f936352014-08-05 14:04:04 +100011597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011598os_device_encoding_impl(PyObject *module, int fd)
11599/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011600{
Brett Cannonefb00c02012-02-29 18:31:31 -050011601 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011602}
11603
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011604
Larry Hastings2f936352014-08-05 14:04:04 +100011605#ifdef HAVE_SETRESUID
11606/*[clinic input]
11607os.setresuid
11608
11609 ruid: uid_t
11610 euid: uid_t
11611 suid: uid_t
11612 /
11613
11614Set the current process's real, effective, and saved user ids.
11615[clinic start generated code]*/
11616
Larry Hastings2f936352014-08-05 14:04:04 +100011617static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011618os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11619/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011620{
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 if (setresuid(ruid, euid, suid) < 0)
11622 return posix_error();
11623 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011624}
Larry Hastings2f936352014-08-05 14:04:04 +100011625#endif /* HAVE_SETRESUID */
11626
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011627
11628#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011629/*[clinic input]
11630os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011631
Larry Hastings2f936352014-08-05 14:04:04 +100011632 rgid: gid_t
11633 egid: gid_t
11634 sgid: gid_t
11635 /
11636
11637Set the current process's real, effective, and saved group ids.
11638[clinic start generated code]*/
11639
Larry Hastings2f936352014-08-05 14:04:04 +100011640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011641os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11642/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011643{
Victor Stinner8c62be82010-05-06 00:08:46 +000011644 if (setresgid(rgid, egid, sgid) < 0)
11645 return posix_error();
11646 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011647}
Larry Hastings2f936352014-08-05 14:04:04 +100011648#endif /* HAVE_SETRESGID */
11649
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011650
11651#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011652/*[clinic input]
11653os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011654
Larry Hastings2f936352014-08-05 14:04:04 +100011655Return a tuple of the current process's real, effective, and saved user ids.
11656[clinic start generated code]*/
11657
Larry Hastings2f936352014-08-05 14:04:04 +100011658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011659os_getresuid_impl(PyObject *module)
11660/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011661{
Victor Stinner8c62be82010-05-06 00:08:46 +000011662 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011663 if (getresuid(&ruid, &euid, &suid) < 0)
11664 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011665 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11666 _PyLong_FromUid(euid),
11667 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011668}
Larry Hastings2f936352014-08-05 14:04:04 +100011669#endif /* HAVE_GETRESUID */
11670
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011671
11672#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011673/*[clinic input]
11674os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011675
Larry Hastings2f936352014-08-05 14:04:04 +100011676Return a tuple of the current process's real, effective, and saved group ids.
11677[clinic start generated code]*/
11678
Larry Hastings2f936352014-08-05 14:04:04 +100011679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011680os_getresgid_impl(PyObject *module)
11681/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011682{
11683 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011684 if (getresgid(&rgid, &egid, &sgid) < 0)
11685 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011686 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11687 _PyLong_FromGid(egid),
11688 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011689}
Larry Hastings2f936352014-08-05 14:04:04 +100011690#endif /* HAVE_GETRESGID */
11691
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011692
Benjamin Peterson9428d532011-09-14 11:45:52 -040011693#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011694/*[clinic input]
11695os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011696
Larry Hastings2f936352014-08-05 14:04:04 +100011697 path: path_t(allow_fd=True)
11698 attribute: path_t
11699 *
11700 follow_symlinks: bool = True
11701
11702Return the value of extended attribute attribute on path.
11703
BNMetricsb9427072018-11-02 15:20:19 +000011704path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011705If follow_symlinks is False, and the last element of the path is a symbolic
11706 link, getxattr will examine the symbolic link itself instead of the file
11707 the link points to.
11708
11709[clinic start generated code]*/
11710
Larry Hastings2f936352014-08-05 14:04:04 +100011711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011712os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011713 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011714/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011715{
11716 Py_ssize_t i;
11717 PyObject *buffer = NULL;
11718
11719 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11720 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011721
Larry Hastings9cf065c2012-06-22 16:30:09 -070011722 for (i = 0; ; i++) {
11723 void *ptr;
11724 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011725 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011726 Py_ssize_t buffer_size = buffer_sizes[i];
11727 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011728 path_error(path);
11729 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011730 }
11731 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11732 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011733 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011734 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011735
Larry Hastings9cf065c2012-06-22 16:30:09 -070011736 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011737 if (path->fd >= 0)
11738 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011739 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011740 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011741 else
Larry Hastings2f936352014-08-05 14:04:04 +100011742 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011743 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011744
Larry Hastings9cf065c2012-06-22 16:30:09 -070011745 if (result < 0) {
11746 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011747 if (errno == ERANGE)
11748 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011749 path_error(path);
11750 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011751 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011752
Larry Hastings9cf065c2012-06-22 16:30:09 -070011753 if (result != buffer_size) {
11754 /* Can only shrink. */
11755 _PyBytes_Resize(&buffer, result);
11756 }
11757 break;
11758 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011759
Larry Hastings9cf065c2012-06-22 16:30:09 -070011760 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011761}
11762
Larry Hastings2f936352014-08-05 14:04:04 +100011763
11764/*[clinic input]
11765os.setxattr
11766
11767 path: path_t(allow_fd=True)
11768 attribute: path_t
11769 value: Py_buffer
11770 flags: int = 0
11771 *
11772 follow_symlinks: bool = True
11773
11774Set extended attribute attribute on path to value.
11775
BNMetricsb9427072018-11-02 15:20:19 +000011776path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011777If follow_symlinks is False, and the last element of the path is a symbolic
11778 link, setxattr will modify the symbolic link itself instead of the file
11779 the link points to.
11780
11781[clinic start generated code]*/
11782
Benjamin Peterson799bd802011-08-31 22:15:17 -040011783static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011784os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011785 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011786/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011787{
Larry Hastings2f936352014-08-05 14:04:04 +100011788 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011789
Larry Hastings2f936352014-08-05 14:04:04 +100011790 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011791 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011792
Benjamin Peterson799bd802011-08-31 22:15:17 -040011793 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011794 if (path->fd > -1)
11795 result = fsetxattr(path->fd, attribute->narrow,
11796 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011797 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011798 result = setxattr(path->narrow, attribute->narrow,
11799 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011800 else
Larry Hastings2f936352014-08-05 14:04:04 +100011801 result = lsetxattr(path->narrow, attribute->narrow,
11802 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011803 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011804
Larry Hastings9cf065c2012-06-22 16:30:09 -070011805 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011806 path_error(path);
11807 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011808 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011809
Larry Hastings2f936352014-08-05 14:04:04 +100011810 Py_RETURN_NONE;
11811}
11812
11813
11814/*[clinic input]
11815os.removexattr
11816
11817 path: path_t(allow_fd=True)
11818 attribute: path_t
11819 *
11820 follow_symlinks: bool = True
11821
11822Remove extended attribute attribute on path.
11823
BNMetricsb9427072018-11-02 15:20:19 +000011824path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011825If follow_symlinks is False, and the last element of the path is a symbolic
11826 link, removexattr will modify the symbolic link itself instead of the file
11827 the link points to.
11828
11829[clinic start generated code]*/
11830
Larry Hastings2f936352014-08-05 14:04:04 +100011831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011832os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011833 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011834/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011835{
11836 ssize_t result;
11837
11838 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11839 return NULL;
11840
11841 Py_BEGIN_ALLOW_THREADS;
11842 if (path->fd > -1)
11843 result = fremovexattr(path->fd, attribute->narrow);
11844 else if (follow_symlinks)
11845 result = removexattr(path->narrow, attribute->narrow);
11846 else
11847 result = lremovexattr(path->narrow, attribute->narrow);
11848 Py_END_ALLOW_THREADS;
11849
11850 if (result) {
11851 return path_error(path);
11852 }
11853
11854 Py_RETURN_NONE;
11855}
11856
11857
11858/*[clinic input]
11859os.listxattr
11860
11861 path: path_t(allow_fd=True, nullable=True) = None
11862 *
11863 follow_symlinks: bool = True
11864
11865Return a list of extended attributes on path.
11866
BNMetricsb9427072018-11-02 15:20:19 +000011867path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011868if path is None, listxattr will examine the current directory.
11869If follow_symlinks is False, and the last element of the path is a symbolic
11870 link, listxattr will examine the symbolic link itself instead of the file
11871 the link points to.
11872[clinic start generated code]*/
11873
Larry Hastings2f936352014-08-05 14:04:04 +100011874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011875os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011876/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011877{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011878 Py_ssize_t i;
11879 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011880 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011881 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011882
Larry Hastings2f936352014-08-05 14:04:04 +100011883 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011884 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011885
Larry Hastings2f936352014-08-05 14:04:04 +100011886 name = path->narrow ? path->narrow : ".";
11887
Larry Hastings9cf065c2012-06-22 16:30:09 -070011888 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011889 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011890 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011891 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011892 Py_ssize_t buffer_size = buffer_sizes[i];
11893 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011894 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011895 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011896 break;
11897 }
11898 buffer = PyMem_MALLOC(buffer_size);
11899 if (!buffer) {
11900 PyErr_NoMemory();
11901 break;
11902 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011903
Larry Hastings9cf065c2012-06-22 16:30:09 -070011904 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011905 if (path->fd > -1)
11906 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011907 else if (follow_symlinks)
11908 length = listxattr(name, buffer, buffer_size);
11909 else
11910 length = llistxattr(name, buffer, buffer_size);
11911 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011912
Larry Hastings9cf065c2012-06-22 16:30:09 -070011913 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011914 if (errno == ERANGE) {
11915 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011916 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011917 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011918 }
Larry Hastings2f936352014-08-05 14:04:04 +100011919 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011920 break;
11921 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011922
Larry Hastings9cf065c2012-06-22 16:30:09 -070011923 result = PyList_New(0);
11924 if (!result) {
11925 goto exit;
11926 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011927
Larry Hastings9cf065c2012-06-22 16:30:09 -070011928 end = buffer + length;
11929 for (trace = start = buffer; trace != end; trace++) {
11930 if (!*trace) {
11931 int error;
11932 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11933 trace - start);
11934 if (!attribute) {
11935 Py_DECREF(result);
11936 result = NULL;
11937 goto exit;
11938 }
11939 error = PyList_Append(result, attribute);
11940 Py_DECREF(attribute);
11941 if (error) {
11942 Py_DECREF(result);
11943 result = NULL;
11944 goto exit;
11945 }
11946 start = trace + 1;
11947 }
11948 }
11949 break;
11950 }
11951exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011952 if (buffer)
11953 PyMem_FREE(buffer);
11954 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011955}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011956#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011957
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011958
Larry Hastings2f936352014-08-05 14:04:04 +100011959/*[clinic input]
11960os.urandom
11961
11962 size: Py_ssize_t
11963 /
11964
11965Return a bytes object containing random bytes suitable for cryptographic use.
11966[clinic start generated code]*/
11967
Larry Hastings2f936352014-08-05 14:04:04 +100011968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011969os_urandom_impl(PyObject *module, Py_ssize_t size)
11970/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011971{
11972 PyObject *bytes;
11973 int result;
11974
Georg Brandl2fb477c2012-02-21 00:33:36 +010011975 if (size < 0)
11976 return PyErr_Format(PyExc_ValueError,
11977 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011978 bytes = PyBytes_FromStringAndSize(NULL, size);
11979 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011980 return NULL;
11981
Victor Stinnere66987e2016-09-06 16:33:52 -070011982 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011983 if (result == -1) {
11984 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011985 return NULL;
11986 }
Larry Hastings2f936352014-08-05 14:04:04 +100011987 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011988}
11989
Zackery Spytz43fdbd22019-05-29 13:57:07 -060011990#ifdef HAVE_MEMFD_CREATE
11991/*[clinic input]
11992os.memfd_create
11993
11994 name: FSConverter
11995 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
11996
11997[clinic start generated code]*/
11998
11999static PyObject *
12000os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12001/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12002{
12003 int fd;
12004 const char *bytes = PyBytes_AS_STRING(name);
12005 Py_BEGIN_ALLOW_THREADS
12006 fd = memfd_create(bytes, flags);
12007 Py_END_ALLOW_THREADS
12008 if (fd == -1) {
12009 return PyErr_SetFromErrno(PyExc_OSError);
12010 }
12011 return PyLong_FromLong(fd);
12012}
12013#endif
12014
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012015/* Terminal size querying */
12016
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012017static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012018
12019PyDoc_STRVAR(TerminalSize_docstring,
12020 "A tuple of (columns, lines) for holding terminal window size");
12021
12022static PyStructSequence_Field TerminalSize_fields[] = {
12023 {"columns", "width of the terminal window in characters"},
12024 {"lines", "height of the terminal window in characters"},
12025 {NULL, NULL}
12026};
12027
12028static PyStructSequence_Desc TerminalSize_desc = {
12029 "os.terminal_size",
12030 TerminalSize_docstring,
12031 TerminalSize_fields,
12032 2,
12033};
12034
12035#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100012036/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012037PyDoc_STRVAR(termsize__doc__,
12038 "Return the size of the terminal window as (columns, lines).\n" \
12039 "\n" \
12040 "The optional argument fd (default standard output) specifies\n" \
12041 "which file descriptor should be queried.\n" \
12042 "\n" \
12043 "If the file descriptor is not connected to a terminal, an OSError\n" \
12044 "is thrown.\n" \
12045 "\n" \
12046 "This function will only be defined if an implementation is\n" \
12047 "available for this system.\n" \
12048 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080012049 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012050 "normally be used, os.get_terminal_size is the low-level implementation.");
12051
12052static PyObject*
12053get_terminal_size(PyObject *self, PyObject *args)
12054{
12055 int columns, lines;
12056 PyObject *termsize;
12057
12058 int fd = fileno(stdout);
12059 /* Under some conditions stdout may not be connected and
12060 * fileno(stdout) may point to an invalid file descriptor. For example
12061 * GUI apps don't have valid standard streams by default.
12062 *
12063 * If this happens, and the optional fd argument is not present,
12064 * the ioctl below will fail returning EBADF. This is what we want.
12065 */
12066
12067 if (!PyArg_ParseTuple(args, "|i", &fd))
12068 return NULL;
12069
12070#ifdef TERMSIZE_USE_IOCTL
12071 {
12072 struct winsize w;
12073 if (ioctl(fd, TIOCGWINSZ, &w))
12074 return PyErr_SetFromErrno(PyExc_OSError);
12075 columns = w.ws_col;
12076 lines = w.ws_row;
12077 }
12078#endif /* TERMSIZE_USE_IOCTL */
12079
12080#ifdef TERMSIZE_USE_CONIO
12081 {
12082 DWORD nhandle;
12083 HANDLE handle;
12084 CONSOLE_SCREEN_BUFFER_INFO csbi;
12085 switch (fd) {
12086 case 0: nhandle = STD_INPUT_HANDLE;
12087 break;
12088 case 1: nhandle = STD_OUTPUT_HANDLE;
12089 break;
12090 case 2: nhandle = STD_ERROR_HANDLE;
12091 break;
12092 default:
12093 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12094 }
12095 handle = GetStdHandle(nhandle);
12096 if (handle == NULL)
12097 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12098 if (handle == INVALID_HANDLE_VALUE)
12099 return PyErr_SetFromWindowsErr(0);
12100
12101 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12102 return PyErr_SetFromWindowsErr(0);
12103
12104 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12105 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12106 }
12107#endif /* TERMSIZE_USE_CONIO */
12108
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012109 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012110 if (termsize == NULL)
12111 return NULL;
12112 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12113 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12114 if (PyErr_Occurred()) {
12115 Py_DECREF(termsize);
12116 return NULL;
12117 }
12118 return termsize;
12119}
12120#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12121
Larry Hastings2f936352014-08-05 14:04:04 +100012122
12123/*[clinic input]
12124os.cpu_count
12125
Charles-François Natali80d62e62015-08-13 20:37:08 +010012126Return the number of CPUs in the system; return None if indeterminable.
12127
12128This number is not equivalent to the number of CPUs the current process can
12129use. The number of usable CPUs can be obtained with
12130``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012131[clinic start generated code]*/
12132
Larry Hastings2f936352014-08-05 14:04:04 +100012133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012134os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012135/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012136{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012137 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012138#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012139 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
12140 Need to fallback to Vista behavior if this call isn't present */
12141 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012142 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010012143 Py_BEGIN_ALLOW_THREADS
12144 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012145 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
12146 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010012147 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012148 if (_GetMaximumProcessorCount != NULL) {
12149 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
12150 }
12151 else {
12152 SYSTEM_INFO sysinfo;
12153 GetSystemInfo(&sysinfo);
12154 ncpu = sysinfo.dwNumberOfProcessors;
12155 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012156#elif defined(__hpux)
12157 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12158#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12159 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012160#elif defined(__DragonFly__) || \
12161 defined(__OpenBSD__) || \
12162 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012163 defined(__NetBSD__) || \
12164 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012165 int mib[2];
12166 size_t len = sizeof(ncpu);
12167 mib[0] = CTL_HW;
12168 mib[1] = HW_NCPU;
12169 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12170 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012171#endif
12172 if (ncpu >= 1)
12173 return PyLong_FromLong(ncpu);
12174 else
12175 Py_RETURN_NONE;
12176}
12177
Victor Stinnerdaf45552013-08-28 00:53:59 +020012178
Larry Hastings2f936352014-08-05 14:04:04 +100012179/*[clinic input]
12180os.get_inheritable -> bool
12181
12182 fd: int
12183 /
12184
12185Get the close-on-exe flag of the specified file descriptor.
12186[clinic start generated code]*/
12187
Larry Hastings2f936352014-08-05 14:04:04 +100012188static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012189os_get_inheritable_impl(PyObject *module, int fd)
12190/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012191{
Steve Dower8fc89802015-04-12 00:26:27 -040012192 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012193 _Py_BEGIN_SUPPRESS_IPH
12194 return_value = _Py_get_inheritable(fd);
12195 _Py_END_SUPPRESS_IPH
12196 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012197}
12198
12199
12200/*[clinic input]
12201os.set_inheritable
12202 fd: int
12203 inheritable: int
12204 /
12205
12206Set the inheritable flag of the specified file descriptor.
12207[clinic start generated code]*/
12208
Larry Hastings2f936352014-08-05 14:04:04 +100012209static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012210os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12211/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012212{
Steve Dower8fc89802015-04-12 00:26:27 -040012213 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012214
Steve Dower8fc89802015-04-12 00:26:27 -040012215 _Py_BEGIN_SUPPRESS_IPH
12216 result = _Py_set_inheritable(fd, inheritable, NULL);
12217 _Py_END_SUPPRESS_IPH
12218 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012219 return NULL;
12220 Py_RETURN_NONE;
12221}
12222
12223
12224#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012225/*[clinic input]
12226os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012227 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012228 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012229
Larry Hastings2f936352014-08-05 14:04:04 +100012230Get the close-on-exe flag of the specified file descriptor.
12231[clinic start generated code]*/
12232
Larry Hastings2f936352014-08-05 14:04:04 +100012233static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012234os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012235/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012236{
12237 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012238
12239 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12240 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012241 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012242 }
12243
Larry Hastings2f936352014-08-05 14:04:04 +100012244 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012245}
12246
Victor Stinnerdaf45552013-08-28 00:53:59 +020012247
Larry Hastings2f936352014-08-05 14:04:04 +100012248/*[clinic input]
12249os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012250 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012251 inheritable: bool
12252 /
12253
12254Set the inheritable flag of the specified handle.
12255[clinic start generated code]*/
12256
Larry Hastings2f936352014-08-05 14:04:04 +100012257static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012258os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012259 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012260/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012261{
12262 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012263 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12264 PyErr_SetFromWindowsErr(0);
12265 return NULL;
12266 }
12267 Py_RETURN_NONE;
12268}
Larry Hastings2f936352014-08-05 14:04:04 +100012269#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012270
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012271#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012272/*[clinic input]
12273os.get_blocking -> bool
12274 fd: int
12275 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012276
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012277Get the blocking mode of the file descriptor.
12278
12279Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12280[clinic start generated code]*/
12281
12282static int
12283os_get_blocking_impl(PyObject *module, int fd)
12284/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012285{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012286 int blocking;
12287
Steve Dower8fc89802015-04-12 00:26:27 -040012288 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012289 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012290 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012291 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012292}
12293
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012294/*[clinic input]
12295os.set_blocking
12296 fd: int
12297 blocking: bool(accept={int})
12298 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012299
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012300Set the blocking mode of the specified file descriptor.
12301
12302Set the O_NONBLOCK flag if blocking is False,
12303clear the O_NONBLOCK flag otherwise.
12304[clinic start generated code]*/
12305
12306static PyObject *
12307os_set_blocking_impl(PyObject *module, int fd, int blocking)
12308/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012309{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012310 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012311
Steve Dower8fc89802015-04-12 00:26:27 -040012312 _Py_BEGIN_SUPPRESS_IPH
12313 result = _Py_set_blocking(fd, blocking);
12314 _Py_END_SUPPRESS_IPH
12315 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012316 return NULL;
12317 Py_RETURN_NONE;
12318}
12319#endif /* !MS_WINDOWS */
12320
12321
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012322/*[clinic input]
12323class os.DirEntry "DirEntry *" "&DirEntryType"
12324[clinic start generated code]*/
12325/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012326
12327typedef struct {
12328 PyObject_HEAD
12329 PyObject *name;
12330 PyObject *path;
12331 PyObject *stat;
12332 PyObject *lstat;
12333#ifdef MS_WINDOWS
12334 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012335 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012336 int got_file_index;
12337#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012338#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012339 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012340#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012341 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012342 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012343#endif
12344} DirEntry;
12345
12346static void
12347DirEntry_dealloc(DirEntry *entry)
12348{
12349 Py_XDECREF(entry->name);
12350 Py_XDECREF(entry->path);
12351 Py_XDECREF(entry->stat);
12352 Py_XDECREF(entry->lstat);
12353 Py_TYPE(entry)->tp_free((PyObject *)entry);
12354}
12355
12356/* Forward reference */
12357static int
12358DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12359
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012360/*[clinic input]
12361os.DirEntry.is_symlink -> bool
12362
12363Return True if the entry is a symbolic link; cached per entry.
12364[clinic start generated code]*/
12365
Victor Stinner6036e442015-03-08 01:58:04 +010012366static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012367os_DirEntry_is_symlink_impl(DirEntry *self)
12368/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012369{
12370#ifdef MS_WINDOWS
12371 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012372#elif defined(HAVE_DIRENT_D_TYPE)
12373 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012374 if (self->d_type != DT_UNKNOWN)
12375 return self->d_type == DT_LNK;
12376 else
12377 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012378#else
12379 /* POSIX without d_type */
12380 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012381#endif
12382}
12383
12384static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012385DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12386{
12387 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012388 STRUCT_STAT st;
12389 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012390
12391#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012392 if (!PyUnicode_FSDecoder(self->path, &ub))
12393 return NULL;
12394 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012395#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012396 if (!PyUnicode_FSConverter(self->path, &ub))
12397 return NULL;
12398 const char *path = PyBytes_AS_STRING(ub);
12399 if (self->dir_fd != DEFAULT_DIR_FD) {
12400#ifdef HAVE_FSTATAT
12401 result = fstatat(self->dir_fd, path, &st,
12402 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12403#else
12404 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12405 return NULL;
12406#endif /* HAVE_FSTATAT */
12407 }
12408 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012409#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012410 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012411 if (follow_symlinks)
12412 result = STAT(path, &st);
12413 else
12414 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012415 }
12416 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012417
12418 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012419 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012420
12421 return _pystat_fromstructstat(&st);
12422}
12423
12424static PyObject *
12425DirEntry_get_lstat(DirEntry *self)
12426{
12427 if (!self->lstat) {
12428#ifdef MS_WINDOWS
12429 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12430#else /* POSIX */
12431 self->lstat = DirEntry_fetch_stat(self, 0);
12432#endif
12433 }
12434 Py_XINCREF(self->lstat);
12435 return self->lstat;
12436}
12437
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012438/*[clinic input]
12439os.DirEntry.stat
12440 *
12441 follow_symlinks: bool = True
12442
12443Return stat_result object for the entry; cached per entry.
12444[clinic start generated code]*/
12445
Victor Stinner6036e442015-03-08 01:58:04 +010012446static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012447os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12448/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012449{
12450 if (!follow_symlinks)
12451 return DirEntry_get_lstat(self);
12452
12453 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012454 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012455 if (result == -1)
12456 return NULL;
12457 else if (result)
12458 self->stat = DirEntry_fetch_stat(self, 1);
12459 else
12460 self->stat = DirEntry_get_lstat(self);
12461 }
12462
12463 Py_XINCREF(self->stat);
12464 return self->stat;
12465}
12466
Victor Stinner6036e442015-03-08 01:58:04 +010012467/* Set exception and return -1 on error, 0 for False, 1 for True */
12468static int
12469DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12470{
12471 PyObject *stat = NULL;
12472 PyObject *st_mode = NULL;
12473 long mode;
12474 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012475#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012476 int is_symlink;
12477 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012478#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012479#ifdef MS_WINDOWS
12480 unsigned long dir_bits;
12481#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012482 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012483
12484#ifdef MS_WINDOWS
12485 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12486 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012487#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012488 is_symlink = self->d_type == DT_LNK;
12489 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12490#endif
12491
Victor Stinner35a97c02015-03-08 02:59:09 +010012492#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012493 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012494#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012495 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012496 if (!stat) {
12497 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12498 /* If file doesn't exist (anymore), then return False
12499 (i.e., say it's not a file/directory) */
12500 PyErr_Clear();
12501 return 0;
12502 }
12503 goto error;
12504 }
12505 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12506 if (!st_mode)
12507 goto error;
12508
12509 mode = PyLong_AsLong(st_mode);
12510 if (mode == -1 && PyErr_Occurred())
12511 goto error;
12512 Py_CLEAR(st_mode);
12513 Py_CLEAR(stat);
12514 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012515#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012516 }
12517 else if (is_symlink) {
12518 assert(mode_bits != S_IFLNK);
12519 result = 0;
12520 }
12521 else {
12522 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12523#ifdef MS_WINDOWS
12524 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12525 if (mode_bits == S_IFDIR)
12526 result = dir_bits != 0;
12527 else
12528 result = dir_bits == 0;
12529#else /* POSIX */
12530 if (mode_bits == S_IFDIR)
12531 result = self->d_type == DT_DIR;
12532 else
12533 result = self->d_type == DT_REG;
12534#endif
12535 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012536#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012537
12538 return result;
12539
12540error:
12541 Py_XDECREF(st_mode);
12542 Py_XDECREF(stat);
12543 return -1;
12544}
12545
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012546/*[clinic input]
12547os.DirEntry.is_dir -> bool
12548 *
12549 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012550
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012551Return True if the entry is a directory; cached per entry.
12552[clinic start generated code]*/
12553
12554static int
12555os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12556/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12557{
12558 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012559}
12560
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012561/*[clinic input]
12562os.DirEntry.is_file -> bool
12563 *
12564 follow_symlinks: bool = True
12565
12566Return True if the entry is a file; cached per entry.
12567[clinic start generated code]*/
12568
12569static int
12570os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12571/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012572{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012573 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012574}
12575
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012576/*[clinic input]
12577os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012578
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012579Return inode of the entry; cached per entry.
12580[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012581
12582static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012583os_DirEntry_inode_impl(DirEntry *self)
12584/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012585{
12586#ifdef MS_WINDOWS
12587 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012588 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012589 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012590 STRUCT_STAT stat;
12591 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012592
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012593 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012594 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012595 path = PyUnicode_AsUnicode(unicode);
12596 result = LSTAT(path, &stat);
12597 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012598
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012599 if (result != 0)
12600 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012601
12602 self->win32_file_index = stat.st_ino;
12603 self->got_file_index = 1;
12604 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012605 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12606 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012607#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012608 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12609 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012610#endif
12611}
12612
12613static PyObject *
12614DirEntry_repr(DirEntry *self)
12615{
12616 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12617}
12618
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012619/*[clinic input]
12620os.DirEntry.__fspath__
12621
12622Returns the path for the entry.
12623[clinic start generated code]*/
12624
Brett Cannon96881cd2016-06-10 14:37:21 -070012625static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012626os_DirEntry___fspath___impl(DirEntry *self)
12627/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012628{
12629 Py_INCREF(self->path);
12630 return self->path;
12631}
12632
Victor Stinner6036e442015-03-08 01:58:04 +010012633static PyMemberDef DirEntry_members[] = {
12634 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12635 "the entry's base filename, relative to scandir() \"path\" argument"},
12636 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12637 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12638 {NULL}
12639};
12640
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012641#include "clinic/posixmodule.c.h"
12642
Victor Stinner6036e442015-03-08 01:58:04 +010012643static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012644 OS_DIRENTRY_IS_DIR_METHODDEF
12645 OS_DIRENTRY_IS_FILE_METHODDEF
12646 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12647 OS_DIRENTRY_STAT_METHODDEF
12648 OS_DIRENTRY_INODE_METHODDEF
12649 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012650 {NULL}
12651};
12652
Benjamin Peterson5646de42015-04-12 17:56:34 -040012653static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012654 PyVarObject_HEAD_INIT(NULL, 0)
12655 MODNAME ".DirEntry", /* tp_name */
12656 sizeof(DirEntry), /* tp_basicsize */
12657 0, /* tp_itemsize */
12658 /* methods */
12659 (destructor)DirEntry_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012660 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010012661 0, /* tp_getattr */
12662 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012663 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010012664 (reprfunc)DirEntry_repr, /* tp_repr */
12665 0, /* tp_as_number */
12666 0, /* tp_as_sequence */
12667 0, /* tp_as_mapping */
12668 0, /* tp_hash */
12669 0, /* tp_call */
12670 0, /* tp_str */
12671 0, /* tp_getattro */
12672 0, /* tp_setattro */
12673 0, /* tp_as_buffer */
12674 Py_TPFLAGS_DEFAULT, /* tp_flags */
12675 0, /* tp_doc */
12676 0, /* tp_traverse */
12677 0, /* tp_clear */
12678 0, /* tp_richcompare */
12679 0, /* tp_weaklistoffset */
12680 0, /* tp_iter */
12681 0, /* tp_iternext */
12682 DirEntry_methods, /* tp_methods */
12683 DirEntry_members, /* tp_members */
12684};
12685
12686#ifdef MS_WINDOWS
12687
12688static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012689join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012690{
12691 Py_ssize_t path_len;
12692 Py_ssize_t size;
12693 wchar_t *result;
12694 wchar_t ch;
12695
12696 if (!path_wide) { /* Default arg: "." */
12697 path_wide = L".";
12698 path_len = 1;
12699 }
12700 else {
12701 path_len = wcslen(path_wide);
12702 }
12703
12704 /* The +1's are for the path separator and the NUL */
12705 size = path_len + 1 + wcslen(filename) + 1;
12706 result = PyMem_New(wchar_t, size);
12707 if (!result) {
12708 PyErr_NoMemory();
12709 return NULL;
12710 }
12711 wcscpy(result, path_wide);
12712 if (path_len > 0) {
12713 ch = result[path_len - 1];
12714 if (ch != SEP && ch != ALTSEP && ch != L':')
12715 result[path_len++] = SEP;
12716 wcscpy(result + path_len, filename);
12717 }
12718 return result;
12719}
12720
12721static PyObject *
12722DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12723{
12724 DirEntry *entry;
12725 BY_HANDLE_FILE_INFORMATION file_info;
12726 ULONG reparse_tag;
12727 wchar_t *joined_path;
12728
12729 entry = PyObject_New(DirEntry, &DirEntryType);
12730 if (!entry)
12731 return NULL;
12732 entry->name = NULL;
12733 entry->path = NULL;
12734 entry->stat = NULL;
12735 entry->lstat = NULL;
12736 entry->got_file_index = 0;
12737
12738 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12739 if (!entry->name)
12740 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012741 if (path->narrow) {
12742 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12743 if (!entry->name)
12744 goto error;
12745 }
Victor Stinner6036e442015-03-08 01:58:04 +010012746
12747 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12748 if (!joined_path)
12749 goto error;
12750
12751 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12752 PyMem_Free(joined_path);
12753 if (!entry->path)
12754 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012755 if (path->narrow) {
12756 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12757 if (!entry->path)
12758 goto error;
12759 }
Victor Stinner6036e442015-03-08 01:58:04 +010012760
Steve Dowercc16be82016-09-08 10:35:16 -070012761 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012762 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12763
12764 return (PyObject *)entry;
12765
12766error:
12767 Py_DECREF(entry);
12768 return NULL;
12769}
12770
12771#else /* POSIX */
12772
12773static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012774join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012775{
12776 Py_ssize_t path_len;
12777 Py_ssize_t size;
12778 char *result;
12779
12780 if (!path_narrow) { /* Default arg: "." */
12781 path_narrow = ".";
12782 path_len = 1;
12783 }
12784 else {
12785 path_len = strlen(path_narrow);
12786 }
12787
12788 if (filename_len == -1)
12789 filename_len = strlen(filename);
12790
12791 /* The +1's are for the path separator and the NUL */
12792 size = path_len + 1 + filename_len + 1;
12793 result = PyMem_New(char, size);
12794 if (!result) {
12795 PyErr_NoMemory();
12796 return NULL;
12797 }
12798 strcpy(result, path_narrow);
12799 if (path_len > 0 && result[path_len - 1] != '/')
12800 result[path_len++] = '/';
12801 strcpy(result + path_len, filename);
12802 return result;
12803}
12804
12805static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012806DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012807 ino_t d_ino
12808#ifdef HAVE_DIRENT_D_TYPE
12809 , unsigned char d_type
12810#endif
12811 )
Victor Stinner6036e442015-03-08 01:58:04 +010012812{
12813 DirEntry *entry;
12814 char *joined_path;
12815
12816 entry = PyObject_New(DirEntry, &DirEntryType);
12817 if (!entry)
12818 return NULL;
12819 entry->name = NULL;
12820 entry->path = NULL;
12821 entry->stat = NULL;
12822 entry->lstat = NULL;
12823
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012824 if (path->fd != -1) {
12825 entry->dir_fd = path->fd;
12826 joined_path = NULL;
12827 }
12828 else {
12829 entry->dir_fd = DEFAULT_DIR_FD;
12830 joined_path = join_path_filename(path->narrow, name, name_len);
12831 if (!joined_path)
12832 goto error;
12833 }
Victor Stinner6036e442015-03-08 01:58:04 +010012834
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012835 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012836 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012837 if (joined_path)
12838 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012839 }
12840 else {
12841 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012842 if (joined_path)
12843 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012844 }
12845 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012846 if (!entry->name)
12847 goto error;
12848
12849 if (path->fd != -1) {
12850 entry->path = entry->name;
12851 Py_INCREF(entry->path);
12852 }
12853 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012854 goto error;
12855
Victor Stinner35a97c02015-03-08 02:59:09 +010012856#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012857 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012858#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012859 entry->d_ino = d_ino;
12860
12861 return (PyObject *)entry;
12862
12863error:
12864 Py_XDECREF(entry);
12865 return NULL;
12866}
12867
12868#endif
12869
12870
12871typedef struct {
12872 PyObject_HEAD
12873 path_t path;
12874#ifdef MS_WINDOWS
12875 HANDLE handle;
12876 WIN32_FIND_DATAW file_data;
12877 int first_time;
12878#else /* POSIX */
12879 DIR *dirp;
12880#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012881#ifdef HAVE_FDOPENDIR
12882 int fd;
12883#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012884} ScandirIterator;
12885
12886#ifdef MS_WINDOWS
12887
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012888static int
12889ScandirIterator_is_closed(ScandirIterator *iterator)
12890{
12891 return iterator->handle == INVALID_HANDLE_VALUE;
12892}
12893
Victor Stinner6036e442015-03-08 01:58:04 +010012894static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012895ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012896{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012897 HANDLE handle = iterator->handle;
12898
12899 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012900 return;
12901
Victor Stinner6036e442015-03-08 01:58:04 +010012902 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012903 Py_BEGIN_ALLOW_THREADS
12904 FindClose(handle);
12905 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012906}
12907
12908static PyObject *
12909ScandirIterator_iternext(ScandirIterator *iterator)
12910{
12911 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12912 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012913 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012914
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012915 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012916 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012917 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012918
12919 while (1) {
12920 if (!iterator->first_time) {
12921 Py_BEGIN_ALLOW_THREADS
12922 success = FindNextFileW(iterator->handle, file_data);
12923 Py_END_ALLOW_THREADS
12924 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012925 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012926 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012927 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012928 break;
12929 }
12930 }
12931 iterator->first_time = 0;
12932
12933 /* Skip over . and .. */
12934 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012935 wcscmp(file_data->cFileName, L"..") != 0) {
12936 entry = DirEntry_from_find_data(&iterator->path, file_data);
12937 if (!entry)
12938 break;
12939 return entry;
12940 }
Victor Stinner6036e442015-03-08 01:58:04 +010012941
12942 /* Loop till we get a non-dot directory or finish iterating */
12943 }
12944
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012945 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012946 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012947 return NULL;
12948}
12949
12950#else /* POSIX */
12951
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012952static int
12953ScandirIterator_is_closed(ScandirIterator *iterator)
12954{
12955 return !iterator->dirp;
12956}
12957
Victor Stinner6036e442015-03-08 01:58:04 +010012958static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012959ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012960{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012961 DIR *dirp = iterator->dirp;
12962
12963 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012964 return;
12965
Victor Stinner6036e442015-03-08 01:58:04 +010012966 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012967 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012968#ifdef HAVE_FDOPENDIR
12969 if (iterator->path.fd != -1)
12970 rewinddir(dirp);
12971#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012972 closedir(dirp);
12973 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012974 return;
12975}
12976
12977static PyObject *
12978ScandirIterator_iternext(ScandirIterator *iterator)
12979{
12980 struct dirent *direntp;
12981 Py_ssize_t name_len;
12982 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012983 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012984
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012985 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012986 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012987 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012988
12989 while (1) {
12990 errno = 0;
12991 Py_BEGIN_ALLOW_THREADS
12992 direntp = readdir(iterator->dirp);
12993 Py_END_ALLOW_THREADS
12994
12995 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012996 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012997 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012998 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012999 break;
13000 }
13001
13002 /* Skip over . and .. */
13003 name_len = NAMLEN(direntp);
13004 is_dot = direntp->d_name[0] == '.' &&
13005 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13006 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013007 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010013008 name_len, direntp->d_ino
13009#ifdef HAVE_DIRENT_D_TYPE
13010 , direntp->d_type
13011#endif
13012 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013013 if (!entry)
13014 break;
13015 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013016 }
13017
13018 /* Loop till we get a non-dot directory or finish iterating */
13019 }
13020
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013021 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013022 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013023 return NULL;
13024}
13025
13026#endif
13027
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013028static PyObject *
13029ScandirIterator_close(ScandirIterator *self, PyObject *args)
13030{
13031 ScandirIterator_closedir(self);
13032 Py_RETURN_NONE;
13033}
13034
13035static PyObject *
13036ScandirIterator_enter(PyObject *self, PyObject *args)
13037{
13038 Py_INCREF(self);
13039 return self;
13040}
13041
13042static PyObject *
13043ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13044{
13045 ScandirIterator_closedir(self);
13046 Py_RETURN_NONE;
13047}
13048
Victor Stinner6036e442015-03-08 01:58:04 +010013049static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013050ScandirIterator_finalize(ScandirIterator *iterator)
13051{
13052 PyObject *error_type, *error_value, *error_traceback;
13053
13054 /* Save the current exception, if any. */
13055 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13056
13057 if (!ScandirIterator_is_closed(iterator)) {
13058 ScandirIterator_closedir(iterator);
13059
13060 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13061 "unclosed scandir iterator %R", iterator)) {
13062 /* Spurious errors can appear at shutdown */
13063 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13064 PyErr_WriteUnraisable((PyObject *) iterator);
13065 }
13066 }
13067 }
13068
Victor Stinner7bfa4092016-03-23 00:43:54 +010013069 path_cleanup(&iterator->path);
13070
13071 /* Restore the saved exception. */
13072 PyErr_Restore(error_type, error_value, error_traceback);
13073}
13074
13075static void
Victor Stinner6036e442015-03-08 01:58:04 +010013076ScandirIterator_dealloc(ScandirIterator *iterator)
13077{
Victor Stinner7bfa4092016-03-23 00:43:54 +010013078 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13079 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013080
Victor Stinner6036e442015-03-08 01:58:04 +010013081 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
13082}
13083
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013084static PyMethodDef ScandirIterator_methods[] = {
13085 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13086 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13087 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13088 {NULL}
13089};
13090
Benjamin Peterson5646de42015-04-12 17:56:34 -040013091static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010013092 PyVarObject_HEAD_INIT(NULL, 0)
13093 MODNAME ".ScandirIterator", /* tp_name */
13094 sizeof(ScandirIterator), /* tp_basicsize */
13095 0, /* tp_itemsize */
13096 /* methods */
13097 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013098 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010013099 0, /* tp_getattr */
13100 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013101 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010013102 0, /* tp_repr */
13103 0, /* tp_as_number */
13104 0, /* tp_as_sequence */
13105 0, /* tp_as_mapping */
13106 0, /* tp_hash */
13107 0, /* tp_call */
13108 0, /* tp_str */
13109 0, /* tp_getattro */
13110 0, /* tp_setattro */
13111 0, /* tp_as_buffer */
Antoine Pitrouada319b2019-05-29 22:12:38 +020013112 Py_TPFLAGS_DEFAULT, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010013113 0, /* tp_doc */
13114 0, /* tp_traverse */
13115 0, /* tp_clear */
13116 0, /* tp_richcompare */
13117 0, /* tp_weaklistoffset */
13118 PyObject_SelfIter, /* tp_iter */
13119 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013120 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010013121 0, /* tp_members */
13122 0, /* tp_getset */
13123 0, /* tp_base */
13124 0, /* tp_dict */
13125 0, /* tp_descr_get */
13126 0, /* tp_descr_set */
13127 0, /* tp_dictoffset */
13128 0, /* tp_init */
13129 0, /* tp_alloc */
13130 0, /* tp_new */
13131 0, /* tp_free */
13132 0, /* tp_is_gc */
13133 0, /* tp_bases */
13134 0, /* tp_mro */
13135 0, /* tp_cache */
13136 0, /* tp_subclasses */
13137 0, /* tp_weaklist */
13138 0, /* tp_del */
13139 0, /* tp_version_tag */
13140 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010013141};
13142
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013143/*[clinic input]
13144os.scandir
13145
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013146 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013147
13148Return an iterator of DirEntry objects for given path.
13149
BNMetricsb9427072018-11-02 15:20:19 +000013150path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013151is bytes, the names of yielded DirEntry objects will also be bytes; in
13152all other circumstances they will be str.
13153
13154If path is None, uses the path='.'.
13155[clinic start generated code]*/
13156
Victor Stinner6036e442015-03-08 01:58:04 +010013157static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013158os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013159/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013160{
13161 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013162#ifdef MS_WINDOWS
13163 wchar_t *path_strW;
13164#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013165 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013166#ifdef HAVE_FDOPENDIR
13167 int fd = -1;
13168#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013169#endif
13170
Steve Dower60419a72019-06-24 08:42:54 -070013171 if (PySys_Audit("os.scandir", "O",
13172 path->object ? path->object : Py_None) < 0) {
13173 return NULL;
13174 }
13175
Victor Stinner6036e442015-03-08 01:58:04 +010013176 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
13177 if (!iterator)
13178 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013179
13180#ifdef MS_WINDOWS
13181 iterator->handle = INVALID_HANDLE_VALUE;
13182#else
13183 iterator->dirp = NULL;
13184#endif
13185
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013186 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013187 /* Move the ownership to iterator->path */
13188 path->object = NULL;
13189 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013190
13191#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013192 iterator->first_time = 1;
13193
13194 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13195 if (!path_strW)
13196 goto error;
13197
13198 Py_BEGIN_ALLOW_THREADS
13199 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13200 Py_END_ALLOW_THREADS
13201
13202 PyMem_Free(path_strW);
13203
13204 if (iterator->handle == INVALID_HANDLE_VALUE) {
13205 path_error(&iterator->path);
13206 goto error;
13207 }
13208#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013209 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013210#ifdef HAVE_FDOPENDIR
13211 if (path->fd != -1) {
13212 /* closedir() closes the FD, so we duplicate it */
13213 fd = _Py_dup(path->fd);
13214 if (fd == -1)
13215 goto error;
13216
13217 Py_BEGIN_ALLOW_THREADS
13218 iterator->dirp = fdopendir(fd);
13219 Py_END_ALLOW_THREADS
13220 }
13221 else
13222#endif
13223 {
13224 if (iterator->path.narrow)
13225 path_str = iterator->path.narrow;
13226 else
13227 path_str = ".";
13228
13229 Py_BEGIN_ALLOW_THREADS
13230 iterator->dirp = opendir(path_str);
13231 Py_END_ALLOW_THREADS
13232 }
Victor Stinner6036e442015-03-08 01:58:04 +010013233
13234 if (!iterator->dirp) {
13235 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013236#ifdef HAVE_FDOPENDIR
13237 if (fd != -1) {
13238 Py_BEGIN_ALLOW_THREADS
13239 close(fd);
13240 Py_END_ALLOW_THREADS
13241 }
13242#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013243 goto error;
13244 }
13245#endif
13246
13247 return (PyObject *)iterator;
13248
13249error:
13250 Py_DECREF(iterator);
13251 return NULL;
13252}
13253
Ethan Furman410ef8e2016-06-04 12:06:26 -070013254/*
13255 Return the file system path representation of the object.
13256
13257 If the object is str or bytes, then allow it to pass through with
13258 an incremented refcount. If the object defines __fspath__(), then
13259 return the result of that method. All other types raise a TypeError.
13260*/
13261PyObject *
13262PyOS_FSPath(PyObject *path)
13263{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013264 /* For error message reasons, this function is manually inlined in
13265 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013266 _Py_IDENTIFIER(__fspath__);
13267 PyObject *func = NULL;
13268 PyObject *path_repr = NULL;
13269
13270 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13271 Py_INCREF(path);
13272 return path;
13273 }
13274
13275 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13276 if (NULL == func) {
13277 return PyErr_Format(PyExc_TypeError,
13278 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013279 "not %.200s",
13280 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013281 }
13282
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013283 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013284 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013285 if (NULL == path_repr) {
13286 return NULL;
13287 }
13288
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013289 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13290 PyErr_Format(PyExc_TypeError,
13291 "expected %.200s.__fspath__() to return str or bytes, "
13292 "not %.200s", Py_TYPE(path)->tp_name,
13293 Py_TYPE(path_repr)->tp_name);
13294 Py_DECREF(path_repr);
13295 return NULL;
13296 }
13297
Ethan Furman410ef8e2016-06-04 12:06:26 -070013298 return path_repr;
13299}
13300
13301/*[clinic input]
13302os.fspath
13303
13304 path: object
13305
13306Return the file system path representation of the object.
13307
Brett Cannonb4f43e92016-06-09 14:32:08 -070013308If the object is str or bytes, then allow it to pass through as-is. If the
13309object defines __fspath__(), then return the result of that method. All other
13310types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013311[clinic start generated code]*/
13312
13313static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013314os_fspath_impl(PyObject *module, PyObject *path)
13315/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013316{
13317 return PyOS_FSPath(path);
13318}
Victor Stinner6036e442015-03-08 01:58:04 +010013319
Victor Stinner9b1f4742016-09-06 16:18:52 -070013320#ifdef HAVE_GETRANDOM_SYSCALL
13321/*[clinic input]
13322os.getrandom
13323
13324 size: Py_ssize_t
13325 flags: int=0
13326
13327Obtain a series of random bytes.
13328[clinic start generated code]*/
13329
13330static PyObject *
13331os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13332/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13333{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013334 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013335 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013336
13337 if (size < 0) {
13338 errno = EINVAL;
13339 return posix_error();
13340 }
13341
Victor Stinnerec2319c2016-09-20 23:00:59 +020013342 bytes = PyBytes_FromStringAndSize(NULL, size);
13343 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013344 PyErr_NoMemory();
13345 return NULL;
13346 }
13347
13348 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013349 n = syscall(SYS_getrandom,
13350 PyBytes_AS_STRING(bytes),
13351 PyBytes_GET_SIZE(bytes),
13352 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013353 if (n < 0 && errno == EINTR) {
13354 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013355 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013356 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013357
13358 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013359 continue;
13360 }
13361 break;
13362 }
13363
13364 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013365 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013366 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013367 }
13368
Victor Stinnerec2319c2016-09-20 23:00:59 +020013369 if (n != size) {
13370 _PyBytes_Resize(&bytes, n);
13371 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013372
13373 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013374
13375error:
13376 Py_DECREF(bytes);
13377 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013378}
13379#endif /* HAVE_GETRANDOM_SYSCALL */
13380
Steve Dower2438cdf2019-03-29 16:37:16 -070013381#ifdef MS_WINDOWS
13382/* bpo-36085: Helper functions for managing DLL search directories
13383 * on win32
13384 */
13385
13386typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13387typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13388
13389/*[clinic input]
13390os._add_dll_directory
13391
13392 path: path_t
13393
13394Add a path to the DLL search path.
13395
13396This search path is used when resolving dependencies for imported
13397extension modules (the module itself is resolved through sys.path),
13398and also by ctypes.
13399
13400Returns an opaque value that may be passed to os.remove_dll_directory
13401to remove this directory from the search path.
13402[clinic start generated code]*/
13403
13404static PyObject *
13405os__add_dll_directory_impl(PyObject *module, path_t *path)
13406/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13407{
13408 HMODULE hKernel32;
13409 PAddDllDirectory AddDllDirectory;
13410 DLL_DIRECTORY_COOKIE cookie = 0;
13411 DWORD err = 0;
13412
13413 /* For Windows 7, we have to load this. As this will be a fairly
13414 infrequent operation, just do it each time. Kernel32 is always
13415 loaded. */
13416 Py_BEGIN_ALLOW_THREADS
13417 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13418 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13419 hKernel32, "AddDllDirectory")) ||
13420 !(cookie = (*AddDllDirectory)(path->wide))) {
13421 err = GetLastError();
13422 }
13423 Py_END_ALLOW_THREADS
13424
13425 if (err) {
13426 return win32_error_object_err("add_dll_directory",
13427 path->object, err);
13428 }
13429
13430 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13431}
13432
13433/*[clinic input]
13434os._remove_dll_directory
13435
13436 cookie: object
13437
13438Removes a path from the DLL search path.
13439
13440The parameter is an opaque value that was returned from
13441os.add_dll_directory. You can only remove directories that you added
13442yourself.
13443[clinic start generated code]*/
13444
13445static PyObject *
13446os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13447/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13448{
13449 HMODULE hKernel32;
13450 PRemoveDllDirectory RemoveDllDirectory;
13451 DLL_DIRECTORY_COOKIE cookieValue;
13452 DWORD err = 0;
13453
13454 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13455 PyErr_SetString(PyExc_TypeError,
13456 "Provided cookie was not returned from os.add_dll_directory");
13457 return NULL;
13458 }
13459
13460 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13461 cookie, "DLL directory cookie");
13462
13463 /* For Windows 7, we have to load this. As this will be a fairly
13464 infrequent operation, just do it each time. Kernel32 is always
13465 loaded. */
13466 Py_BEGIN_ALLOW_THREADS
13467 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13468 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13469 hKernel32, "RemoveDllDirectory")) ||
13470 !(*RemoveDllDirectory)(cookieValue)) {
13471 err = GetLastError();
13472 }
13473 Py_END_ALLOW_THREADS
13474
13475 if (err) {
13476 return win32_error_object_err("remove_dll_directory",
13477 NULL, err);
13478 }
13479
13480 if (PyCapsule_SetName(cookie, NULL)) {
13481 return NULL;
13482 }
13483
13484 Py_RETURN_NONE;
13485}
13486
13487#endif
Larry Hastings31826802013-10-19 00:09:25 -070013488
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013489static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013490
13491 OS_STAT_METHODDEF
13492 OS_ACCESS_METHODDEF
13493 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013494 OS_CHDIR_METHODDEF
13495 OS_CHFLAGS_METHODDEF
13496 OS_CHMOD_METHODDEF
13497 OS_FCHMOD_METHODDEF
13498 OS_LCHMOD_METHODDEF
13499 OS_CHOWN_METHODDEF
13500 OS_FCHOWN_METHODDEF
13501 OS_LCHOWN_METHODDEF
13502 OS_LCHFLAGS_METHODDEF
13503 OS_CHROOT_METHODDEF
13504 OS_CTERMID_METHODDEF
13505 OS_GETCWD_METHODDEF
13506 OS_GETCWDB_METHODDEF
13507 OS_LINK_METHODDEF
13508 OS_LISTDIR_METHODDEF
13509 OS_LSTAT_METHODDEF
13510 OS_MKDIR_METHODDEF
13511 OS_NICE_METHODDEF
13512 OS_GETPRIORITY_METHODDEF
13513 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013514 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013515 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013516 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013517 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013518 OS_RENAME_METHODDEF
13519 OS_REPLACE_METHODDEF
13520 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013521 OS_SYMLINK_METHODDEF
13522 OS_SYSTEM_METHODDEF
13523 OS_UMASK_METHODDEF
13524 OS_UNAME_METHODDEF
13525 OS_UNLINK_METHODDEF
13526 OS_REMOVE_METHODDEF
13527 OS_UTIME_METHODDEF
13528 OS_TIMES_METHODDEF
13529 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013530 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013531 OS_EXECV_METHODDEF
13532 OS_EXECVE_METHODDEF
13533 OS_SPAWNV_METHODDEF
13534 OS_SPAWNVE_METHODDEF
13535 OS_FORK1_METHODDEF
13536 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013537 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013538 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13539 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13540 OS_SCHED_GETPARAM_METHODDEF
13541 OS_SCHED_GETSCHEDULER_METHODDEF
13542 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13543 OS_SCHED_SETPARAM_METHODDEF
13544 OS_SCHED_SETSCHEDULER_METHODDEF
13545 OS_SCHED_YIELD_METHODDEF
13546 OS_SCHED_SETAFFINITY_METHODDEF
13547 OS_SCHED_GETAFFINITY_METHODDEF
13548 OS_OPENPTY_METHODDEF
13549 OS_FORKPTY_METHODDEF
13550 OS_GETEGID_METHODDEF
13551 OS_GETEUID_METHODDEF
13552 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013553#ifdef HAVE_GETGROUPLIST
13554 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13555#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013556 OS_GETGROUPS_METHODDEF
13557 OS_GETPID_METHODDEF
13558 OS_GETPGRP_METHODDEF
13559 OS_GETPPID_METHODDEF
13560 OS_GETUID_METHODDEF
13561 OS_GETLOGIN_METHODDEF
13562 OS_KILL_METHODDEF
13563 OS_KILLPG_METHODDEF
13564 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013565#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013566 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013567#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013568 OS_SETUID_METHODDEF
13569 OS_SETEUID_METHODDEF
13570 OS_SETREUID_METHODDEF
13571 OS_SETGID_METHODDEF
13572 OS_SETEGID_METHODDEF
13573 OS_SETREGID_METHODDEF
13574 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013575#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013576 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013577#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013578 OS_GETPGID_METHODDEF
13579 OS_SETPGRP_METHODDEF
13580 OS_WAIT_METHODDEF
13581 OS_WAIT3_METHODDEF
13582 OS_WAIT4_METHODDEF
13583 OS_WAITID_METHODDEF
13584 OS_WAITPID_METHODDEF
13585 OS_GETSID_METHODDEF
13586 OS_SETSID_METHODDEF
13587 OS_SETPGID_METHODDEF
13588 OS_TCGETPGRP_METHODDEF
13589 OS_TCSETPGRP_METHODDEF
13590 OS_OPEN_METHODDEF
13591 OS_CLOSE_METHODDEF
13592 OS_CLOSERANGE_METHODDEF
13593 OS_DEVICE_ENCODING_METHODDEF
13594 OS_DUP_METHODDEF
13595 OS_DUP2_METHODDEF
13596 OS_LOCKF_METHODDEF
13597 OS_LSEEK_METHODDEF
13598 OS_READ_METHODDEF
13599 OS_READV_METHODDEF
13600 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013601 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013602 OS_WRITE_METHODDEF
13603 OS_WRITEV_METHODDEF
13604 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013605 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013606#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013607 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013608 posix_sendfile__doc__},
13609#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013610 OS_FSTAT_METHODDEF
13611 OS_ISATTY_METHODDEF
13612 OS_PIPE_METHODDEF
13613 OS_PIPE2_METHODDEF
13614 OS_MKFIFO_METHODDEF
13615 OS_MKNOD_METHODDEF
13616 OS_MAJOR_METHODDEF
13617 OS_MINOR_METHODDEF
13618 OS_MAKEDEV_METHODDEF
13619 OS_FTRUNCATE_METHODDEF
13620 OS_TRUNCATE_METHODDEF
13621 OS_POSIX_FALLOCATE_METHODDEF
13622 OS_POSIX_FADVISE_METHODDEF
13623 OS_PUTENV_METHODDEF
13624 OS_UNSETENV_METHODDEF
13625 OS_STRERROR_METHODDEF
13626 OS_FCHDIR_METHODDEF
13627 OS_FSYNC_METHODDEF
13628 OS_SYNC_METHODDEF
13629 OS_FDATASYNC_METHODDEF
13630 OS_WCOREDUMP_METHODDEF
13631 OS_WIFCONTINUED_METHODDEF
13632 OS_WIFSTOPPED_METHODDEF
13633 OS_WIFSIGNALED_METHODDEF
13634 OS_WIFEXITED_METHODDEF
13635 OS_WEXITSTATUS_METHODDEF
13636 OS_WTERMSIG_METHODDEF
13637 OS_WSTOPSIG_METHODDEF
13638 OS_FSTATVFS_METHODDEF
13639 OS_STATVFS_METHODDEF
13640 OS_CONFSTR_METHODDEF
13641 OS_SYSCONF_METHODDEF
13642 OS_FPATHCONF_METHODDEF
13643 OS_PATHCONF_METHODDEF
13644 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013645 OS__GETFULLPATHNAME_METHODDEF
13646 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013647 OS__GETDISKUSAGE_METHODDEF
13648 OS__GETFINALPATHNAME_METHODDEF
13649 OS__GETVOLUMEPATHNAME_METHODDEF
13650 OS_GETLOADAVG_METHODDEF
13651 OS_URANDOM_METHODDEF
13652 OS_SETRESUID_METHODDEF
13653 OS_SETRESGID_METHODDEF
13654 OS_GETRESUID_METHODDEF
13655 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013656
Larry Hastings2f936352014-08-05 14:04:04 +100013657 OS_GETXATTR_METHODDEF
13658 OS_SETXATTR_METHODDEF
13659 OS_REMOVEXATTR_METHODDEF
13660 OS_LISTXATTR_METHODDEF
13661
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013662#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13663 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13664#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013665 OS_CPU_COUNT_METHODDEF
13666 OS_GET_INHERITABLE_METHODDEF
13667 OS_SET_INHERITABLE_METHODDEF
13668 OS_GET_HANDLE_INHERITABLE_METHODDEF
13669 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013670#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013671 OS_GET_BLOCKING_METHODDEF
13672 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013673#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013674 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013675 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013676 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013677 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013678#ifdef MS_WINDOWS
13679 OS__ADD_DLL_DIRECTORY_METHODDEF
13680 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13681#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013682 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013683};
13684
Barry Warsaw4a342091996-12-19 23:50:02 +000013685static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013686all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013687{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013688#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013689 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013690#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013691#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013692 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013693#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013694#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013695 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013696#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013697#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013698 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013699#endif
Fred Drakec9680921999-12-13 16:37:25 +000013700#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013701 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013702#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013703#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013704 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013705#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013706#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013707 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013708#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013709#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013710 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013711#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013712#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013713 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013714#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013715#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013716 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013717#endif
13718#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013719 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013720#endif
13721#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013722 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013723#endif
13724#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013725 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013726#endif
13727#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013728 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013729#endif
13730#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013731 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013732#endif
13733#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013734 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013735#endif
13736#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013737 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013738#endif
13739#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013740 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013741#endif
13742#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013743 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013744#endif
13745#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013746 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013747#endif
13748#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013749 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013750#endif
13751#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013752 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013753#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013754#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013755 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013756#endif
13757#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013758 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013759#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013760#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013761 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013762#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013763#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013764 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013765#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013766#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013767#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013768 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013769#endif
13770#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013771 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013772#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013773#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013774#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013775 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013776#endif
13777#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013778 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013779#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013780#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013781 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013782#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013783#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013784 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013785#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013786#ifdef O_TMPFILE
13787 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13788#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013789#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013790 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013791#endif
13792#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013793 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013794#endif
13795#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013796 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013797#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013798#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013799 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013800#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013801#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013802 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013803#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013804
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013805
Jesus Cea94363612012-06-22 18:32:07 +020013806#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013807 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013808#endif
13809#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013810 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013811#endif
13812
Tim Peters5aa91602002-01-30 05:46:57 +000013813/* MS Windows */
13814#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013815 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013816 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013817#endif
13818#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013819 /* Optimize for short life (keep in memory). */
13820 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013821 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013822#endif
13823#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013824 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013825 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013826#endif
13827#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013828 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013829 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013830#endif
13831#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013832 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013833 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013834#endif
13835
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013836/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013837#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013838 /* Send a SIGIO signal whenever input or output
13839 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013840 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013841#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013842#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013843 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013844 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013845#endif
13846#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013847 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013848 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013849#endif
13850#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013851 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013852 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013853#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013854#ifdef O_NOLINKS
13855 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013856 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013857#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013858#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013859 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013860 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013861#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013862
Victor Stinner8c62be82010-05-06 00:08:46 +000013863 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013864#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013865 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013866#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013867#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013868 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013869#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013870#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013871 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013872#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013873#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013874 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013875#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013876#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013877 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013878#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013879#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013880 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013881#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013882#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013883 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013884#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013885#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013886 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013887#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013888#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013889 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013890#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013891#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013892 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013893#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013894#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013895 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013896#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013897#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013898 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013899#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013900#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013901 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013902#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013903#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013904 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013905#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013906#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013907 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013908#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013909#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013910 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013911#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013912#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013913 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013914#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013915
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013916 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013917#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013918 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013919#endif /* ST_RDONLY */
13920#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013921 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013922#endif /* ST_NOSUID */
13923
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013924 /* GNU extensions */
13925#ifdef ST_NODEV
13926 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13927#endif /* ST_NODEV */
13928#ifdef ST_NOEXEC
13929 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13930#endif /* ST_NOEXEC */
13931#ifdef ST_SYNCHRONOUS
13932 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13933#endif /* ST_SYNCHRONOUS */
13934#ifdef ST_MANDLOCK
13935 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13936#endif /* ST_MANDLOCK */
13937#ifdef ST_WRITE
13938 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13939#endif /* ST_WRITE */
13940#ifdef ST_APPEND
13941 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13942#endif /* ST_APPEND */
13943#ifdef ST_NOATIME
13944 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13945#endif /* ST_NOATIME */
13946#ifdef ST_NODIRATIME
13947 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13948#endif /* ST_NODIRATIME */
13949#ifdef ST_RELATIME
13950 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13951#endif /* ST_RELATIME */
13952
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013953 /* FreeBSD sendfile() constants */
13954#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013955 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013956#endif
13957#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013958 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013959#endif
13960#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013961 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013962#endif
13963
Ross Lagerwall7807c352011-03-17 20:20:30 +020013964 /* constants for posix_fadvise */
13965#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013966 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013967#endif
13968#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013969 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013970#endif
13971#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013972 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013973#endif
13974#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013975 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013976#endif
13977#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013978 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013979#endif
13980#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013981 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013982#endif
13983
13984 /* constants for waitid */
13985#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013986 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13987 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13988 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013989#endif
13990#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013991 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013992#endif
13993#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013994 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013995#endif
13996#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013997 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013998#endif
13999#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014000 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014001#endif
14002#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014003 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014004#endif
14005#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014006 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014007#endif
14008#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014009 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014010#endif
14011
14012 /* constants for lockf */
14013#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014014 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014015#endif
14016#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014017 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014018#endif
14019#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014020 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014021#endif
14022#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014023 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014024#endif
14025
Pablo Galindo4defba32018-01-27 16:16:37 +000014026#ifdef RWF_DSYNC
14027 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14028#endif
14029#ifdef RWF_HIPRI
14030 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14031#endif
14032#ifdef RWF_SYNC
14033 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14034#endif
14035#ifdef RWF_NOWAIT
14036 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14037#endif
14038
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014039/* constants for posix_spawn */
14040#ifdef HAVE_POSIX_SPAWN
14041 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14042 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14043 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14044#endif
14045
pxinwrf2d7ac72019-05-21 18:46:37 +080014046#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014047 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14048 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014049 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014050#endif
14051#ifdef HAVE_SPAWNV
14052 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014053 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014054#endif
14055
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014056#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014057#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014058 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014059#endif
14060#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014061 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014062#endif
14063#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014064 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014065#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014066#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014067 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014068#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014069#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014070 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014071#endif
14072#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014073 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014074#endif
14075#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014076 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014077#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014078#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014079 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014080#endif
14081#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014082 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014083#endif
14084#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014085 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014086#endif
14087#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014088 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014089#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014090#endif
14091
Benjamin Peterson9428d532011-09-14 11:45:52 -040014092#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014093 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14094 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14095 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014096#endif
14097
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014098#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014099 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014100#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014101#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014102 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014103#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014104#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014105 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014106#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014107#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014108 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014109#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014110#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014111 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014112#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014113#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014114 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014115#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014116#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014117 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014118#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014119#if HAVE_DECL_RTLD_MEMBER
14120 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14121#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014122
Victor Stinner9b1f4742016-09-06 16:18:52 -070014123#ifdef HAVE_GETRANDOM_SYSCALL
14124 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14125 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14126#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014127#ifdef HAVE_MEMFD_CREATE
14128 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14129 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14130#ifdef MFD_HUGETLB
14131 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014132#endif
14133#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014134 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014135#endif
14136#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014137 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014138#endif
14139#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014140 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014141#endif
14142#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014143 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014144#endif
14145#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014146 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014147#endif
14148#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014149 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014150#endif
14151#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014152 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014153#endif
14154#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014155 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014156#endif
14157#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014158 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014159#endif
14160#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014161 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014162#endif
14163#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014164 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014165#endif
14166#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014167 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014168#endif
14169#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014170 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014171#endif
14172#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014173 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14174#endif
14175#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014176
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014177#if defined(__APPLE__)
14178 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14179#endif
14180
Steve Dower2438cdf2019-03-29 16:37:16 -070014181#ifdef MS_WINDOWS
14182 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14183 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14184 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14185 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14186 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14187#endif
14188
Victor Stinner8c62be82010-05-06 00:08:46 +000014189 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014190}
14191
14192
Martin v. Löwis1a214512008-06-11 05:26:20 +000014193static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014194 PyModuleDef_HEAD_INIT,
14195 MODNAME,
14196 posix__doc__,
14197 -1,
14198 posix_methods,
14199 NULL,
14200 NULL,
14201 NULL,
14202 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000014203};
14204
14205
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014206static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014207
14208#ifdef HAVE_FACCESSAT
14209 "HAVE_FACCESSAT",
14210#endif
14211
14212#ifdef HAVE_FCHDIR
14213 "HAVE_FCHDIR",
14214#endif
14215
14216#ifdef HAVE_FCHMOD
14217 "HAVE_FCHMOD",
14218#endif
14219
14220#ifdef HAVE_FCHMODAT
14221 "HAVE_FCHMODAT",
14222#endif
14223
14224#ifdef HAVE_FCHOWN
14225 "HAVE_FCHOWN",
14226#endif
14227
Larry Hastings00964ed2013-08-12 13:49:30 -040014228#ifdef HAVE_FCHOWNAT
14229 "HAVE_FCHOWNAT",
14230#endif
14231
Larry Hastings9cf065c2012-06-22 16:30:09 -070014232#ifdef HAVE_FEXECVE
14233 "HAVE_FEXECVE",
14234#endif
14235
14236#ifdef HAVE_FDOPENDIR
14237 "HAVE_FDOPENDIR",
14238#endif
14239
Georg Brandl306336b2012-06-24 12:55:33 +020014240#ifdef HAVE_FPATHCONF
14241 "HAVE_FPATHCONF",
14242#endif
14243
Larry Hastings9cf065c2012-06-22 16:30:09 -070014244#ifdef HAVE_FSTATAT
14245 "HAVE_FSTATAT",
14246#endif
14247
14248#ifdef HAVE_FSTATVFS
14249 "HAVE_FSTATVFS",
14250#endif
14251
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014252#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014253 "HAVE_FTRUNCATE",
14254#endif
14255
Larry Hastings9cf065c2012-06-22 16:30:09 -070014256#ifdef HAVE_FUTIMENS
14257 "HAVE_FUTIMENS",
14258#endif
14259
14260#ifdef HAVE_FUTIMES
14261 "HAVE_FUTIMES",
14262#endif
14263
14264#ifdef HAVE_FUTIMESAT
14265 "HAVE_FUTIMESAT",
14266#endif
14267
14268#ifdef HAVE_LINKAT
14269 "HAVE_LINKAT",
14270#endif
14271
14272#ifdef HAVE_LCHFLAGS
14273 "HAVE_LCHFLAGS",
14274#endif
14275
14276#ifdef HAVE_LCHMOD
14277 "HAVE_LCHMOD",
14278#endif
14279
14280#ifdef HAVE_LCHOWN
14281 "HAVE_LCHOWN",
14282#endif
14283
14284#ifdef HAVE_LSTAT
14285 "HAVE_LSTAT",
14286#endif
14287
14288#ifdef HAVE_LUTIMES
14289 "HAVE_LUTIMES",
14290#endif
14291
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014292#ifdef HAVE_MEMFD_CREATE
14293 "HAVE_MEMFD_CREATE",
14294#endif
14295
Larry Hastings9cf065c2012-06-22 16:30:09 -070014296#ifdef HAVE_MKDIRAT
14297 "HAVE_MKDIRAT",
14298#endif
14299
14300#ifdef HAVE_MKFIFOAT
14301 "HAVE_MKFIFOAT",
14302#endif
14303
14304#ifdef HAVE_MKNODAT
14305 "HAVE_MKNODAT",
14306#endif
14307
14308#ifdef HAVE_OPENAT
14309 "HAVE_OPENAT",
14310#endif
14311
14312#ifdef HAVE_READLINKAT
14313 "HAVE_READLINKAT",
14314#endif
14315
14316#ifdef HAVE_RENAMEAT
14317 "HAVE_RENAMEAT",
14318#endif
14319
14320#ifdef HAVE_SYMLINKAT
14321 "HAVE_SYMLINKAT",
14322#endif
14323
14324#ifdef HAVE_UNLINKAT
14325 "HAVE_UNLINKAT",
14326#endif
14327
14328#ifdef HAVE_UTIMENSAT
14329 "HAVE_UTIMENSAT",
14330#endif
14331
14332#ifdef MS_WINDOWS
14333 "MS_WINDOWS",
14334#endif
14335
14336 NULL
14337};
14338
14339
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014340PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014341INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014342{
Victor Stinner8c62be82010-05-06 00:08:46 +000014343 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014344 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014345 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014346
Victor Stinner8c62be82010-05-06 00:08:46 +000014347 m = PyModule_Create(&posixmodule);
14348 if (m == NULL)
14349 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014350
Victor Stinner8c62be82010-05-06 00:08:46 +000014351 /* Initialize environ dictionary */
14352 v = convertenviron();
14353 Py_XINCREF(v);
14354 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14355 return NULL;
14356 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014357
Victor Stinner8c62be82010-05-06 00:08:46 +000014358 if (all_ins(m))
14359 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014360
Victor Stinner8c62be82010-05-06 00:08:46 +000014361 if (setup_confname_tables(m))
14362 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014363
Victor Stinner8c62be82010-05-06 00:08:46 +000014364 Py_INCREF(PyExc_OSError);
14365 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014366
Guido van Rossumb3d39562000-01-31 18:41:26 +000014367#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014368 if (posix_putenv_garbage == NULL)
14369 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014370#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014371
Victor Stinner8c62be82010-05-06 00:08:46 +000014372 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014373#if defined(HAVE_WAITID) && !defined(__APPLE__)
14374 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014375 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14376 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014377 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014378 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014379#endif
14380
Christian Heimes25827622013-10-12 01:27:08 +020014381 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014382 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14383 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14384 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014385 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14386 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014387 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014388 }
14389 structseq_new = StatResultType->tp_new;
14390 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014391
Christian Heimes25827622013-10-12 01:27:08 +020014392 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014393 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14394 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014395 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014396 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014397#ifdef NEED_TICKS_PER_SECOND
14398# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014399 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014400# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014401 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014402# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014403 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014404# endif
14405#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014406
William Orr81574b82018-10-01 22:19:56 -070014407#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014408 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014409 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14410 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014411 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014412 }
14413 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014414#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014415
14416 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014417 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14418 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014419 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014420 }
Victor Stinner6036e442015-03-08 01:58:04 +010014421
14422 /* initialize scandir types */
14423 if (PyType_Ready(&ScandirIteratorType) < 0)
14424 return NULL;
14425 if (PyType_Ready(&DirEntryType) < 0)
14426 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014427 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014428#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014429 Py_INCREF((PyObject*) WaitidResultType);
14430 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014431#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014432 Py_INCREF((PyObject*) StatResultType);
14433 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14434 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014435 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014436 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014437
14438#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014439 Py_INCREF(SchedParamType);
14440 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014441#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014442
Larry Hastings605a62d2012-06-24 04:33:36 -070014443 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014444 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14445 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014446 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014447 }
14448 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014449
14450 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014451 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14452 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014453 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014454 }
14455 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014456
Thomas Wouters477c8d52006-05-27 19:21:47 +000014457#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014458 /*
14459 * Step 2 of weak-linking support on Mac OS X.
14460 *
14461 * The code below removes functions that are not available on the
14462 * currently active platform.
14463 *
14464 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014465 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014466 * OSX 10.4.
14467 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014468#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014469 if (fstatvfs == NULL) {
14470 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14471 return NULL;
14472 }
14473 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014474#endif /* HAVE_FSTATVFS */
14475
14476#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014477 if (statvfs == NULL) {
14478 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14479 return NULL;
14480 }
14481 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014482#endif /* HAVE_STATVFS */
14483
14484# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014485 if (lchown == NULL) {
14486 if (PyObject_DelAttrString(m, "lchown") == -1) {
14487 return NULL;
14488 }
14489 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014490#endif /* HAVE_LCHOWN */
14491
14492
14493#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014494
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014495 Py_INCREF(TerminalSizeType);
14496 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014497
Larry Hastings6fe20b32012-04-19 15:07:49 -070014498 billion = PyLong_FromLong(1000000000);
14499 if (!billion)
14500 return NULL;
14501
Larry Hastings9cf065c2012-06-22 16:30:09 -070014502 /* suppress "function not used" warnings */
14503 {
14504 int ignored;
14505 fd_specified("", -1);
14506 follow_symlinks_specified("", 1);
14507 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14508 dir_fd_converter(Py_None, &ignored);
14509 dir_fd_unavailable(Py_None, &ignored);
14510 }
14511
14512 /*
14513 * provide list of locally available functions
14514 * so os.py can populate support_* lists
14515 */
14516 list = PyList_New(0);
14517 if (!list)
14518 return NULL;
14519 for (trace = have_functions; *trace; trace++) {
14520 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14521 if (!unicode)
14522 return NULL;
14523 if (PyList_Append(list, unicode))
14524 return NULL;
14525 Py_DECREF(unicode);
14526 }
14527 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014528
14529 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014530 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014531
14532 initialized = 1;
14533
Victor Stinner8c62be82010-05-06 00:08:46 +000014534 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014535}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014536
14537#ifdef __cplusplus
14538}
14539#endif