blob: 2302678ccc14ce2b2858203d8cd940c5836ff851 [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);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200436 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200437 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
Larry Hastings9cf065c2012-06-22 16:30:09 -0700509
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200510#ifndef MS_WINDOWS
511PyObject *
512_PyLong_FromUid(uid_t uid)
513{
514 if (uid == (uid_t)-1)
515 return PyLong_FromLong(-1);
516 return PyLong_FromUnsignedLong(uid);
517}
518
519PyObject *
520_PyLong_FromGid(gid_t gid)
521{
522 if (gid == (gid_t)-1)
523 return PyLong_FromLong(-1);
524 return PyLong_FromUnsignedLong(gid);
525}
526
527int
528_Py_Uid_Converter(PyObject *obj, void *p)
529{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 uid_t uid;
531 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200533 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700534 unsigned long uresult;
535
536 index = PyNumber_Index(obj);
537 if (index == NULL) {
538 PyErr_Format(PyExc_TypeError,
539 "uid should be integer, not %.200s",
540 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200541 return 0;
542 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700543
544 /*
545 * Handling uid_t is complicated for two reasons:
546 * * Although uid_t is (always?) unsigned, it still
547 * accepts -1.
548 * * We don't know its size in advance--it may be
549 * bigger than an int, or it may be smaller than
550 * a long.
551 *
552 * So a bit of defensive programming is in order.
553 * Start with interpreting the value passed
554 * in as a signed long and see if it works.
555 */
556
557 result = PyLong_AsLongAndOverflow(index, &overflow);
558
559 if (!overflow) {
560 uid = (uid_t)result;
561
562 if (result == -1) {
563 if (PyErr_Occurred())
564 goto fail;
565 /* It's a legitimate -1, we're done. */
566 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200567 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700568
569 /* Any other negative number is disallowed. */
570 if (result < 0)
571 goto underflow;
572
573 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575 (long)uid != result)
576 goto underflow;
577 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200578 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700579
580 if (overflow < 0)
581 goto underflow;
582
583 /*
584 * Okay, the value overflowed a signed long. If it
585 * fits in an *unsigned* long, it may still be okay,
586 * as uid_t may be unsigned long on this platform.
587 */
588 uresult = PyLong_AsUnsignedLong(index);
589 if (PyErr_Occurred()) {
590 if (PyErr_ExceptionMatches(PyExc_OverflowError))
591 goto overflow;
592 goto fail;
593 }
594
595 uid = (uid_t)uresult;
596
597 /*
598 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
599 * but this value would get interpreted as (uid_t)-1 by chown
600 * and its siblings. That's not what the user meant! So we
601 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100602 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700603 */
604 if (uid == (uid_t)-1)
605 goto overflow;
606
607 /* Ensure the value wasn't truncated. */
608 if (sizeof(uid_t) < sizeof(long) &&
609 (unsigned long)uid != uresult)
610 goto overflow;
611 /* fallthrough */
612
613success:
614 Py_DECREF(index);
615 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 return 1;
617
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 "uid is less than minimum");
621 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700625 "uid is greater than maximum");
626 /* fallthrough */
627
628fail:
629 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 return 0;
631}
632
633int
634_Py_Gid_Converter(PyObject *obj, void *p)
635{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700636 gid_t gid;
637 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200638 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200639 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640 unsigned long uresult;
641
642 index = PyNumber_Index(obj);
643 if (index == NULL) {
644 PyErr_Format(PyExc_TypeError,
645 "gid should be integer, not %.200s",
646 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200647 return 0;
648 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700649
650 /*
651 * Handling gid_t is complicated for two reasons:
652 * * Although gid_t is (always?) unsigned, it still
653 * accepts -1.
654 * * We don't know its size in advance--it may be
655 * bigger than an int, or it may be smaller than
656 * a long.
657 *
658 * So a bit of defensive programming is in order.
659 * Start with interpreting the value passed
660 * in as a signed long and see if it works.
661 */
662
663 result = PyLong_AsLongAndOverflow(index, &overflow);
664
665 if (!overflow) {
666 gid = (gid_t)result;
667
668 if (result == -1) {
669 if (PyErr_Occurred())
670 goto fail;
671 /* It's a legitimate -1, we're done. */
672 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200673 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700674
675 /* Any other negative number is disallowed. */
676 if (result < 0) {
677 goto underflow;
678 }
679
680 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200681 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700682 (long)gid != result)
683 goto underflow;
684 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200685 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700686
687 if (overflow < 0)
688 goto underflow;
689
690 /*
691 * Okay, the value overflowed a signed long. If it
692 * fits in an *unsigned* long, it may still be okay,
693 * as gid_t may be unsigned long on this platform.
694 */
695 uresult = PyLong_AsUnsignedLong(index);
696 if (PyErr_Occurred()) {
697 if (PyErr_ExceptionMatches(PyExc_OverflowError))
698 goto overflow;
699 goto fail;
700 }
701
702 gid = (gid_t)uresult;
703
704 /*
705 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
706 * but this value would get interpreted as (gid_t)-1 by chown
707 * and its siblings. That's not what the user meant! So we
708 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100709 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700710 */
711 if (gid == (gid_t)-1)
712 goto overflow;
713
714 /* Ensure the value wasn't truncated. */
715 if (sizeof(gid_t) < sizeof(long) &&
716 (unsigned long)gid != uresult)
717 goto overflow;
718 /* fallthrough */
719
720success:
721 Py_DECREF(index);
722 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200723 return 1;
724
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700725underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200726 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700727 "gid is less than minimum");
728 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200731 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700732 "gid is greater than maximum");
733 /* fallthrough */
734
735fail:
736 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200737 return 0;
738}
739#endif /* MS_WINDOWS */
740
741
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700742#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800743
744
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200745#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
746static int
747_Py_Dev_Converter(PyObject *obj, void *p)
748{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200749 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200750 if (PyErr_Occurred())
751 return 0;
752 return 1;
753}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800754#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200755
756
Larry Hastings9cf065c2012-06-22 16:30:09 -0700757#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400758/*
759 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
760 * without the int cast, the value gets interpreted as uint (4291925331),
761 * which doesn't play nicely with all the initializer lines in this file that
762 * look like this:
763 * int dir_fd = DEFAULT_DIR_FD;
764 */
765#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700766#else
767#define DEFAULT_DIR_FD (-100)
768#endif
769
770static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300771_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200772{
773 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700774 long long_value;
775
776 PyObject *index = PyNumber_Index(o);
777 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700778 return 0;
779 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300781 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700782 long_value = PyLong_AsLongAndOverflow(index, &overflow);
783 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300784 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200785 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700787 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700788 return 0;
789 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200790 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700791 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700792 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700793 return 0;
794 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700795
Larry Hastings9cf065c2012-06-22 16:30:09 -0700796 *p = (int)long_value;
797 return 1;
798}
799
800static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200801dir_fd_converter(PyObject *o, void *p)
802{
803 if (o == Py_None) {
804 *(int *)p = DEFAULT_DIR_FD;
805 return 1;
806 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300807 else if (PyIndex_Check(o)) {
808 return _fd_converter(o, (int *)p);
809 }
810 else {
811 PyErr_Format(PyExc_TypeError,
812 "argument should be integer or None, not %.200s",
813 Py_TYPE(o)->tp_name);
814 return 0;
815 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816}
817
818
Larry Hastings9cf065c2012-06-22 16:30:09 -0700819/*
820 * A PyArg_ParseTuple "converter" function
821 * that handles filesystem paths in the manner
822 * preferred by the os module.
823 *
824 * path_converter accepts (Unicode) strings and their
825 * subclasses, and bytes and their subclasses. What
826 * it does with the argument depends on the platform:
827 *
828 * * On Windows, if we get a (Unicode) string we
829 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700830 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700831 *
832 * * On all other platforms, strings are encoded
833 * to bytes using PyUnicode_FSConverter, then we
834 * extract the char * from the bytes object and
835 * return that.
836 *
837 * path_converter also optionally accepts signed
838 * integers (representing open file descriptors) instead
839 * of path strings.
840 *
841 * Input fields:
842 * path.nullable
843 * If nonzero, the path is permitted to be None.
844 * path.allow_fd
845 * If nonzero, the path is permitted to be a file handle
846 * (a signed int) instead of a string.
847 * path.function_name
848 * If non-NULL, path_converter will use that as the name
849 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700850 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700851 * path.argument_name
852 * If non-NULL, path_converter will use that as the name
853 * of the parameter in error messages.
854 * (If path.argument_name is NULL it uses "path".)
855 *
856 * Output fields:
857 * path.wide
858 * Points to the path if it was expressed as Unicode
859 * and was not encoded. (Only used on Windows.)
860 * path.narrow
861 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700862 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000863 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700864 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700865 * path.fd
866 * Contains a file descriptor if path.accept_fd was true
867 * and the caller provided a signed integer instead of any
868 * sort of string.
869 *
870 * WARNING: if your "path" parameter is optional, and is
871 * unspecified, path_converter will never get called.
872 * So if you set allow_fd, you *MUST* initialize path.fd = -1
873 * yourself!
874 * path.length
875 * The length of the path in characters, if specified as
876 * a string.
877 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800878 * The original object passed in (if get a PathLike object,
879 * the result of PyOS_FSPath() is treated as the original object).
880 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881 * path.cleanup
882 * For internal use only. May point to a temporary object.
883 * (Pay no attention to the man behind the curtain.)
884 *
885 * At most one of path.wide or path.narrow will be non-NULL.
886 * If path was None and path.nullable was set,
887 * or if path was an integer and path.allow_fd was set,
888 * both path.wide and path.narrow will be NULL
889 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200890 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700891 * path_converter takes care to not write to the path_t
892 * unless it's successful. However it must reset the
893 * "cleanup" field each time it's called.
894 *
895 * Use as follows:
896 * path_t path;
897 * memset(&path, 0, sizeof(path));
898 * PyArg_ParseTuple(args, "O&", path_converter, &path);
899 * // ... use values from path ...
900 * path_cleanup(&path);
901 *
902 * (Note that if PyArg_Parse fails you don't need to call
903 * path_cleanup(). However it is safe to do so.)
904 */
905typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100906 const char *function_name;
907 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 int nullable;
909 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300910 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700911#ifdef MS_WINDOWS
912 BOOL narrow;
913#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300914 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700915#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700916 int fd;
917 Py_ssize_t length;
918 PyObject *object;
919 PyObject *cleanup;
920} path_t;
921
Steve Dowercc16be82016-09-08 10:35:16 -0700922#ifdef MS_WINDOWS
923#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
924 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
925#else
Larry Hastings2f936352014-08-05 14:04:04 +1000926#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
927 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700928#endif
Larry Hastings31826802013-10-19 00:09:25 -0700929
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800931path_cleanup(path_t *path)
932{
933 Py_CLEAR(path->object);
934 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935}
936
937static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300938path_converter(PyObject *o, void *p)
939{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800941 PyObject *bytes = NULL;
942 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700943 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300944 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700945#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800946 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700947 const wchar_t *wide;
948#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700949
950#define FORMAT_EXCEPTION(exc, fmt) \
951 PyErr_Format(exc, "%s%s" fmt, \
952 path->function_name ? path->function_name : "", \
953 path->function_name ? ": " : "", \
954 path->argument_name ? path->argument_name : "path")
955
956 /* Py_CLEANUP_SUPPORTED support */
957 if (o == NULL) {
958 path_cleanup(path);
959 return 1;
960 }
961
Brett Cannon3f9183b2016-08-26 14:44:48 -0700962 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800963 path->object = path->cleanup = NULL;
964 /* path->object owns a reference to the original object */
965 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300967 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700969#ifdef MS_WINDOWS
970 path->narrow = FALSE;
971#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700972 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700973#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700974 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800975 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700976 }
977
Brett Cannon3f9183b2016-08-26 14:44:48 -0700978 /* Only call this here so that we don't treat the return value of
979 os.fspath() as an fd or buffer. */
980 is_index = path->allow_fd && PyIndex_Check(o);
981 is_buffer = PyObject_CheckBuffer(o);
982 is_bytes = PyBytes_Check(o);
983 is_unicode = PyUnicode_Check(o);
984
985 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
986 /* Inline PyOS_FSPath() for better error messages. */
987 _Py_IDENTIFIER(__fspath__);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000988 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700989
990 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
991 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800992 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700993 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000994 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700995 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000996 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700997 goto error_exit;
998 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000999 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001000 is_unicode = 1;
1001 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001002 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001003 is_bytes = 1;
1004 }
1005 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001006 PyErr_Format(PyExc_TypeError,
1007 "expected %.200s.__fspath__() to return str or bytes, "
1008 "not %.200s", Py_TYPE(o)->tp_name,
1009 Py_TYPE(res)->tp_name);
1010 Py_DECREF(res);
1011 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001012 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001013
1014 /* still owns a reference to the original object */
1015 Py_DECREF(o);
1016 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001017 }
1018
1019 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001020#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001021 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001022 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001023 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001024 }
Victor Stinner59799a82013-11-13 14:17:30 +01001025 if (length > 32767) {
1026 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001027 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001028 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001029 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001030 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001031 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001032 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001033
1034 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001035 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001036 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001037 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001039 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001040 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001041 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001042#endif
1043 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001044 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001045 bytes = o;
1046 Py_INCREF(bytes);
1047 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001048 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001049 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001050 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001051 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1052 "%s%s%s should be %s, not %.200s",
1053 path->function_name ? path->function_name : "",
1054 path->function_name ? ": " : "",
1055 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001056 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1057 "integer or None" :
1058 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1059 path->nullable ? "string, bytes, os.PathLike or None" :
1060 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001061 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001063 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001064 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001066 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001067 }
1068 }
Steve Dowercc16be82016-09-08 10:35:16 -07001069 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001070 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001071 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001072 }
1073 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001074#ifdef MS_WINDOWS
1075 path->narrow = FALSE;
1076#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001077 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001078#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001079 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001080 }
1081 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001082 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001083 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1084 path->function_name ? path->function_name : "",
1085 path->function_name ? ": " : "",
1086 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001087 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1088 "integer or None" :
1089 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1090 path->nullable ? "string, bytes, os.PathLike or None" :
1091 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001092 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001093 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001094 }
1095
Larry Hastings9cf065c2012-06-22 16:30:09 -07001096 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001097 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001098 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001099 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001100 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001101 }
1102
Steve Dowercc16be82016-09-08 10:35:16 -07001103#ifdef MS_WINDOWS
1104 wo = PyUnicode_DecodeFSDefaultAndSize(
1105 narrow,
1106 length
1107 );
1108 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001110 }
1111
Xiang Zhang04316c42017-01-08 23:26:57 +08001112 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001113 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001114 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001115 }
1116 if (length > 32767) {
1117 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001118 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001119 }
1120 if (wcslen(wide) != length) {
1121 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001122 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001123 }
1124 path->wide = wide;
1125 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001126 path->cleanup = wo;
1127 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001128#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 path->wide = NULL;
1130 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001131 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001132 /* Still a reference owned by path->object, don't have to
1133 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001134 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001135 }
1136 else {
1137 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001138 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001139#endif
1140 path->fd = -1;
1141
1142 success_exit:
1143 path->length = length;
1144 path->object = o;
1145 return Py_CLEANUP_SUPPORTED;
1146
1147 error_exit:
1148 Py_XDECREF(o);
1149 Py_XDECREF(bytes);
1150#ifdef MS_WINDOWS
1151 Py_XDECREF(wo);
1152#endif
1153 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001154}
1155
1156static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001157argument_unavailable_error(const char *function_name, const char *argument_name)
1158{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001159 PyErr_Format(PyExc_NotImplementedError,
1160 "%s%s%s unavailable on this platform",
1161 (function_name != NULL) ? function_name : "",
1162 (function_name != NULL) ? ": ": "",
1163 argument_name);
1164}
1165
1166static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001167dir_fd_unavailable(PyObject *o, void *p)
1168{
1169 int dir_fd;
1170 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001171 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001172 if (dir_fd != DEFAULT_DIR_FD) {
1173 argument_unavailable_error(NULL, "dir_fd");
1174 return 0;
1175 }
1176 *(int *)p = dir_fd;
1177 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001178}
1179
1180static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001181fd_specified(const char *function_name, int fd)
1182{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001183 if (fd == -1)
1184 return 0;
1185
1186 argument_unavailable_error(function_name, "fd");
1187 return 1;
1188}
1189
1190static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001191follow_symlinks_specified(const char *function_name, int follow_symlinks)
1192{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001193 if (follow_symlinks)
1194 return 0;
1195
1196 argument_unavailable_error(function_name, "follow_symlinks");
1197 return 1;
1198}
1199
1200static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001201path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1202{
Steve Dowercc16be82016-09-08 10:35:16 -07001203 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1204#ifndef MS_WINDOWS
1205 && !path->narrow
1206#endif
1207 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001208 PyErr_Format(PyExc_ValueError,
1209 "%s: can't specify dir_fd without matching path",
1210 function_name);
1211 return 1;
1212 }
1213 return 0;
1214}
1215
1216static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001217dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1220 PyErr_Format(PyExc_ValueError,
1221 "%s: can't specify both dir_fd and fd",
1222 function_name);
1223 return 1;
1224 }
1225 return 0;
1226}
1227
1228static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001229fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1230 int follow_symlinks)
1231{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001232 if ((fd > 0) && (!follow_symlinks)) {
1233 PyErr_Format(PyExc_ValueError,
1234 "%s: cannot use fd and follow_symlinks together",
1235 function_name);
1236 return 1;
1237 }
1238 return 0;
1239}
1240
1241static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001242dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1243 int follow_symlinks)
1244{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001245 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1246 PyErr_Format(PyExc_ValueError,
1247 "%s: cannot use dir_fd and follow_symlinks together",
1248 function_name);
1249 return 1;
1250 }
1251 return 0;
1252}
1253
Larry Hastings2f936352014-08-05 14:04:04 +10001254#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001255 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001256#else
Larry Hastings2f936352014-08-05 14:04:04 +10001257 typedef off_t Py_off_t;
1258#endif
1259
1260static int
1261Py_off_t_converter(PyObject *arg, void *addr)
1262{
1263#ifdef HAVE_LARGEFILE_SUPPORT
1264 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1265#else
1266 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001267#endif
1268 if (PyErr_Occurred())
1269 return 0;
1270 return 1;
1271}
Larry Hastings2f936352014-08-05 14:04:04 +10001272
1273static PyObject *
1274PyLong_FromPy_off_t(Py_off_t offset)
1275{
1276#ifdef HAVE_LARGEFILE_SUPPORT
1277 return PyLong_FromLongLong(offset);
1278#else
1279 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001280#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001281}
1282
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001283#ifdef HAVE_SIGSET_T
1284/* Convert an iterable of integers to a sigset.
1285 Return 1 on success, return 0 and raise an exception on error. */
1286int
1287_Py_Sigset_Converter(PyObject *obj, void *addr)
1288{
1289 sigset_t *mask = (sigset_t *)addr;
1290 PyObject *iterator, *item;
1291 long signum;
1292 int overflow;
1293
Rémi Lapeyref0900192019-05-04 01:30:53 +02001294 // The extra parens suppress the unreachable-code warning with clang on MacOS
1295 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001296 /* Probably only if mask == NULL. */
1297 PyErr_SetFromErrno(PyExc_OSError);
1298 return 0;
1299 }
1300
1301 iterator = PyObject_GetIter(obj);
1302 if (iterator == NULL) {
1303 return 0;
1304 }
1305
1306 while ((item = PyIter_Next(iterator)) != NULL) {
1307 signum = PyLong_AsLongAndOverflow(item, &overflow);
1308 Py_DECREF(item);
1309 if (signum <= 0 || signum >= NSIG) {
1310 if (overflow || signum != -1 || !PyErr_Occurred()) {
1311 PyErr_Format(PyExc_ValueError,
1312 "signal number %ld out of range", signum);
1313 }
1314 goto error;
1315 }
1316 if (sigaddset(mask, (int)signum)) {
1317 if (errno != EINVAL) {
1318 /* Probably impossible */
1319 PyErr_SetFromErrno(PyExc_OSError);
1320 goto error;
1321 }
1322 /* For backwards compatibility, allow idioms such as
1323 * `range(1, NSIG)` but warn about invalid signal numbers
1324 */
1325 const char msg[] =
1326 "invalid signal number %ld, please use valid_signals()";
1327 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1328 goto error;
1329 }
1330 }
1331 }
1332 if (!PyErr_Occurred()) {
1333 Py_DECREF(iterator);
1334 return 1;
1335 }
1336
1337error:
1338 Py_DECREF(iterator);
1339 return 0;
1340}
1341#endif /* HAVE_SIGSET_T */
1342
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001343#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001344
1345static int
Brian Curtind25aef52011-06-13 15:16:04 -05001346win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001347{
Martin Panter70214ad2016-08-04 02:38:59 +00001348 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1349 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001350 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001351
1352 if (0 == DeviceIoControl(
1353 reparse_point_handle,
1354 FSCTL_GET_REPARSE_POINT,
1355 NULL, 0, /* in buffer */
1356 target_buffer, sizeof(target_buffer),
1357 &n_bytes_returned,
1358 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001359 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001360
1361 if (reparse_tag)
1362 *reparse_tag = rdb->ReparseTag;
1363
Brian Curtind25aef52011-06-13 15:16:04 -05001364 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001365}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001366
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001367#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001368
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001370#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001371/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001372** environ directly, we must obtain it with _NSGetEnviron(). See also
1373** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001374*/
1375#include <crt_externs.h>
1376static char **environ;
pxinwrf2d7ac72019-05-21 18:46:37 +08001377#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001378extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001379#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001380
Barry Warsaw53699e91996-12-10 23:23:01 +00001381static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001382convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001383{
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001385#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001387#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001389#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001390
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 d = PyDict_New();
1392 if (d == NULL)
1393 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001394#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001395 if (environ == NULL)
1396 environ = *_NSGetEnviron();
1397#endif
1398#ifdef MS_WINDOWS
1399 /* _wenviron must be initialized in this way if the program is started
1400 through main() instead of wmain(). */
1401 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001402 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001403#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001404 e = environ;
1405#endif
1406 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001408 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001409 PyObject *k;
1410 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001411#ifdef MS_WINDOWS
1412 const wchar_t *p = wcschr(*e, L'=');
1413#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001414 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001415#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 if (p == NULL)
1417 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001418#ifdef MS_WINDOWS
1419 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1420#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001421 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001422#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001424 Py_DECREF(d);
1425 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001427#ifdef MS_WINDOWS
1428 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1429#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001430 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001431#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001433 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001434 Py_DECREF(d);
1435 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001436 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001437 if (PyDict_GetItemWithError(d, k) == NULL) {
1438 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1439 Py_DECREF(v);
1440 Py_DECREF(k);
1441 Py_DECREF(d);
1442 return NULL;
1443 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 }
1445 Py_DECREF(k);
1446 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001447 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449}
1450
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001451/* Set a POSIX-specific error from errno, and return NULL */
1452
Barry Warsawd58d7641998-07-23 16:14:40 +00001453static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001454posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001455{
Victor Stinner8c62be82010-05-06 00:08:46 +00001456 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001457}
Mark Hammondef8b6542001-05-13 08:04:26 +00001458
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001459#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001460static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001461win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001462{
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 /* XXX We should pass the function name along in the future.
1464 (winreg.c also wants to pass the function name.)
1465 This would however require an additional param to the
1466 Windows error object, which is non-trivial.
1467 */
1468 errno = GetLastError();
1469 if (filename)
1470 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1471 else
1472 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001473}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001474
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001475static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001476win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001477{
1478 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001479 if (filename)
1480 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001481 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001482 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001483 filename);
1484 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001485 return PyErr_SetFromWindowsErr(err);
1486}
1487
1488static PyObject *
1489win32_error_object(const char* function, PyObject* filename)
1490{
1491 errno = GetLastError();
1492 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001493}
1494
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001495#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001496
Larry Hastings9cf065c2012-06-22 16:30:09 -07001497static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001498posix_path_object_error(PyObject *path)
1499{
1500 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1501}
1502
1503static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001504path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001505{
1506#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001507 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1508 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001509#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001510 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001511#endif
1512}
1513
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001514static PyObject *
1515path_object_error2(PyObject *path, PyObject *path2)
1516{
1517#ifdef MS_WINDOWS
1518 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1519 PyExc_OSError, 0, path, path2);
1520#else
1521 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1522#endif
1523}
1524
1525static PyObject *
1526path_error(path_t *path)
1527{
1528 return path_object_error(path->object);
1529}
Larry Hastings31826802013-10-19 00:09:25 -07001530
Larry Hastingsb0827312014-02-09 22:05:19 -08001531static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001532posix_path_error(path_t *path)
1533{
1534 return posix_path_object_error(path->object);
1535}
1536
1537static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001538path_error2(path_t *path, path_t *path2)
1539{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001540 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001541}
1542
1543
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001544/* POSIX generic methods */
1545
Larry Hastings2f936352014-08-05 14:04:04 +10001546static int
1547fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001548{
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001550 int *pointer = (int *)p;
1551 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001553 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001554 *pointer = fd;
1555 return 1;
1556}
1557
1558static PyObject *
1559posix_fildes_fd(int fd, int (*func)(int))
1560{
1561 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001562 int async_err = 0;
1563
1564 do {
1565 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001566 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001567 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001568 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001569 Py_END_ALLOW_THREADS
1570 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1571 if (res != 0)
1572 return (!async_err) ? posix_error() : NULL;
1573 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001574}
Guido van Rossum21142a01999-01-08 21:05:37 +00001575
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001576
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001577#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001578/* This is a reimplementation of the C library's chdir function,
1579 but one that produces Win32 errors instead of DOS error codes.
1580 chdir is essentially a wrapper around SetCurrentDirectory; however,
1581 it also needs to set "magic" environment variables indicating
1582 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001583static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001584win32_wchdir(LPCWSTR path)
1585{
Victor Stinnered537822015-12-13 21:40:26 +01001586 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001587 int result;
1588 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001589
Victor Stinner8c62be82010-05-06 00:08:46 +00001590 if(!SetCurrentDirectoryW(path))
1591 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001592 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001593 if (!result)
1594 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001595 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001596 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 if (!new_path) {
1598 SetLastError(ERROR_OUTOFMEMORY);
1599 return FALSE;
1600 }
1601 result = GetCurrentDirectoryW(result, new_path);
1602 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001603 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 return FALSE;
1605 }
1606 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001607 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1608 wcsncmp(new_path, L"//", 2) == 0);
1609 if (!is_unc_like_path) {
1610 env[1] = new_path[0];
1611 result = SetEnvironmentVariableW(env, new_path);
1612 }
Victor Stinnered537822015-12-13 21:40:26 +01001613 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001614 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001615 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001616}
1617#endif
1618
Martin v. Löwis14694662006-02-03 12:54:16 +00001619#ifdef MS_WINDOWS
1620/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1621 - time stamps are restricted to second resolution
1622 - file modification times suffer from forth-and-back conversions between
1623 UTC and local time
1624 Therefore, we implement our own stat, based on the Win32 API directly.
1625*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001626#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001627#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001628#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001629
Victor Stinner6036e442015-03-08 01:58:04 +01001630static void
Steve Dowercc16be82016-09-08 10:35:16 -07001631find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1632 BY_HANDLE_FILE_INFORMATION *info,
1633 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001634{
1635 memset(info, 0, sizeof(*info));
1636 info->dwFileAttributes = pFileData->dwFileAttributes;
1637 info->ftCreationTime = pFileData->ftCreationTime;
1638 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1639 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1640 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1641 info->nFileSizeLow = pFileData->nFileSizeLow;
1642/* info->nNumberOfLinks = 1; */
1643 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1644 *reparse_tag = pFileData->dwReserved0;
1645 else
1646 *reparse_tag = 0;
1647}
1648
Guido van Rossumd8faa362007-04-27 19:54:29 +00001649static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001650attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001651{
Victor Stinner8c62be82010-05-06 00:08:46 +00001652 HANDLE hFindFile;
1653 WIN32_FIND_DATAW FileData;
1654 hFindFile = FindFirstFileW(pszFile, &FileData);
1655 if (hFindFile == INVALID_HANDLE_VALUE)
1656 return FALSE;
1657 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001658 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001659 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001660}
1661
Brian Curtind25aef52011-06-13 15:16:04 -05001662static int
Steve Dowercc16be82016-09-08 10:35:16 -07001663win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001664 BOOL traverse)
1665{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001666 HANDLE hFile;
1667 BY_HANDLE_FILE_INFORMATION fileInfo;
1668 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1669 DWORD fileType, error;
1670 BOOL isUnhandledTag = FALSE;
1671 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001673 DWORD access = FILE_READ_ATTRIBUTES;
1674 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1675 if (!traverse) {
1676 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1677 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001678
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001679 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001681 /* Either the path doesn't exist, or the caller lacks access. */
1682 error = GetLastError();
1683 switch (error) {
1684 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1685 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1686 /* Try reading the parent directory. */
1687 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1688 /* Cannot read the parent directory. */
1689 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001690 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001692 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1693 if (traverse ||
1694 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1695 /* The stat call has to traverse but cannot, so fail. */
1696 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001697 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001698 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001699 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001700 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001702 case ERROR_INVALID_PARAMETER:
1703 /* \\.\con requires read or write access. */
1704 hFile = CreateFileW(path, access | GENERIC_READ,
1705 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1706 OPEN_EXISTING, flags, NULL);
1707 if (hFile == INVALID_HANDLE_VALUE) {
1708 SetLastError(error);
1709 return -1;
1710 }
1711 break;
1712
1713 case ERROR_CANT_ACCESS_FILE:
1714 /* bpo37834: open unhandled reparse points if traverse fails. */
1715 if (traverse) {
1716 traverse = FALSE;
1717 isUnhandledTag = TRUE;
1718 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1719 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1720 }
1721 if (hFile == INVALID_HANDLE_VALUE) {
1722 SetLastError(error);
1723 return -1;
1724 }
1725 break;
1726
1727 default:
1728 return -1;
1729 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001730 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001731
1732 if (hFile != INVALID_HANDLE_VALUE) {
1733 /* Handle types other than files on disk. */
1734 fileType = GetFileType(hFile);
1735 if (fileType != FILE_TYPE_DISK) {
1736 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1737 retval = -1;
1738 goto cleanup;
1739 }
1740 DWORD fileAttributes = GetFileAttributesW(path);
1741 memset(result, 0, sizeof(*result));
1742 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1743 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1744 /* \\.\pipe\ or \\.\mailslot\ */
1745 result->st_mode = _S_IFDIR;
1746 } else if (fileType == FILE_TYPE_CHAR) {
1747 /* \\.\nul */
1748 result->st_mode = _S_IFCHR;
1749 } else if (fileType == FILE_TYPE_PIPE) {
1750 /* \\.\pipe\spam */
1751 result->st_mode = _S_IFIFO;
1752 }
1753 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1754 goto cleanup;
1755 }
1756
1757 /* Query the reparse tag, and traverse a non-link. */
1758 if (!traverse) {
1759 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1760 &tagInfo, sizeof(tagInfo))) {
1761 /* Allow devices that do not support FileAttributeTagInfo. */
1762 switch (GetLastError()) {
1763 case ERROR_INVALID_PARAMETER:
1764 case ERROR_INVALID_FUNCTION:
1765 case ERROR_NOT_SUPPORTED:
1766 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1767 tagInfo.ReparseTag = 0;
1768 break;
1769 default:
1770 retval = -1;
1771 goto cleanup;
1772 }
1773 } else if (tagInfo.FileAttributes &
1774 FILE_ATTRIBUTE_REPARSE_POINT) {
1775 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1776 if (isUnhandledTag) {
1777 /* Traversing previously failed for either this link
1778 or its target. */
1779 SetLastError(ERROR_CANT_ACCESS_FILE);
1780 retval = -1;
1781 goto cleanup;
1782 }
1783 /* Traverse a non-link, but not if traversing already failed
1784 for an unhandled tag. */
1785 } else if (!isUnhandledTag) {
1786 CloseHandle(hFile);
1787 return win32_xstat_impl(path, result, TRUE);
1788 }
1789 }
1790 }
1791
1792 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1793 switch (GetLastError()) {
1794 case ERROR_INVALID_PARAMETER:
1795 case ERROR_INVALID_FUNCTION:
1796 case ERROR_NOT_SUPPORTED:
1797 retval = -1;
1798 goto cleanup;
1799 }
1800 /* Volumes and physical disks are block devices, e.g.
1801 \\.\C: and \\.\PhysicalDrive0. */
1802 memset(result, 0, sizeof(*result));
1803 result->st_mode = 0x6000; /* S_IFBLK */
1804 goto cleanup;
1805 }
1806 }
1807
1808 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1809
1810 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1811 /* Fix the file execute permissions. This hack sets S_IEXEC if
1812 the filename has an extension that is commonly used by files
1813 that CreateProcessW can execute. A real implementation calls
1814 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1815 AccessCheck to check for generic read, write, and execute
1816 access. */
1817 const wchar_t *fileExtension = wcsrchr(path, '.');
1818 if (fileExtension) {
1819 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1820 _wcsicmp(fileExtension, L".bat") == 0 ||
1821 _wcsicmp(fileExtension, L".cmd") == 0 ||
1822 _wcsicmp(fileExtension, L".com") == 0) {
1823 result->st_mode |= 0111;
1824 }
1825 }
1826 }
1827
1828cleanup:
1829 if (hFile != INVALID_HANDLE_VALUE) {
1830 CloseHandle(hFile);
1831 }
1832
1833 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001834}
1835
1836static int
Steve Dowercc16be82016-09-08 10:35:16 -07001837win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001838{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001839 /* Protocol violation: we explicitly clear errno, instead of
1840 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001841 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001842 errno = 0;
1843 return code;
1844}
Brian Curtind25aef52011-06-13 15:16:04 -05001845/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001846
1847 In Posix, stat automatically traverses symlinks and returns the stat
1848 structure for the target. In Windows, the equivalent GetFileAttributes by
1849 default does not traverse symlinks and instead returns attributes for
1850 the symlink.
1851
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001852 Instead, we will open the file (which *does* traverse symlinks by default)
1853 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001854
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001855static int
Steve Dowercc16be82016-09-08 10:35:16 -07001856win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001857{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001858 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001859}
1860
Victor Stinner8c62be82010-05-06 00:08:46 +00001861static int
Steve Dowercc16be82016-09-08 10:35:16 -07001862win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001863{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001864 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001865}
1866
Martin v. Löwis14694662006-02-03 12:54:16 +00001867#endif /* MS_WINDOWS */
1868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001870"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001871This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001872 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001873or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1874\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001875Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1876or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001877\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879
1880static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 {"st_mode", "protection bits"},
1882 {"st_ino", "inode"},
1883 {"st_dev", "device"},
1884 {"st_nlink", "number of hard links"},
1885 {"st_uid", "user ID of owner"},
1886 {"st_gid", "group ID of owner"},
1887 {"st_size", "total size, in bytes"},
1888 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1889 {NULL, "integer time of last access"},
1890 {NULL, "integer time of last modification"},
1891 {NULL, "integer time of last change"},
1892 {"st_atime", "time of last access"},
1893 {"st_mtime", "time of last modification"},
1894 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001895 {"st_atime_ns", "time of last access in nanoseconds"},
1896 {"st_mtime_ns", "time of last modification in nanoseconds"},
1897 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001898#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001899 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001900#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001901#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001902 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001903#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001904#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001907#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001909#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001910#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001912#endif
1913#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001915#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001916#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1917 {"st_file_attributes", "Windows file attribute bits"},
1918#endif
jcea6c51d512018-01-28 14:00:08 +01001919#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1920 {"st_fstype", "Type of filesystem"},
1921#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001922#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
1923 {"st_reparse_tag", "Windows reparse tag"},
1924#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001926};
1927
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001928#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001929#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001930#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001931#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932#endif
1933
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001934#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001935#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1936#else
1937#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1938#endif
1939
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001940#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001941#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1942#else
1943#define ST_RDEV_IDX ST_BLOCKS_IDX
1944#endif
1945
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001946#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1947#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1948#else
1949#define ST_FLAGS_IDX ST_RDEV_IDX
1950#endif
1951
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001952#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001953#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001954#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001955#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001956#endif
1957
1958#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1959#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1960#else
1961#define ST_BIRTHTIME_IDX ST_GEN_IDX
1962#endif
1963
Zachary Ware63f277b2014-06-19 09:46:37 -05001964#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1965#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1966#else
1967#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1968#endif
1969
jcea6c51d512018-01-28 14:00:08 +01001970#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1971#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1972#else
1973#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1974#endif
1975
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001976#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
1977#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
1978#else
1979#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
1980#endif
1981
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001982static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 "stat_result", /* name */
1984 stat_result__doc__, /* doc */
1985 stat_result_fields,
1986 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001987};
1988
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001989PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001990"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1991This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001992 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001993or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001994\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001995See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001996
1997static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001998 {"f_bsize", },
1999 {"f_frsize", },
2000 {"f_blocks", },
2001 {"f_bfree", },
2002 {"f_bavail", },
2003 {"f_files", },
2004 {"f_ffree", },
2005 {"f_favail", },
2006 {"f_flag", },
2007 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002008 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002010};
2011
2012static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 "statvfs_result", /* name */
2014 statvfs_result__doc__, /* doc */
2015 statvfs_result_fields,
2016 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002017};
2018
Ross Lagerwall7807c352011-03-17 20:20:30 +02002019#if defined(HAVE_WAITID) && !defined(__APPLE__)
2020PyDoc_STRVAR(waitid_result__doc__,
2021"waitid_result: Result from waitid.\n\n\
2022This object may be accessed either as a tuple of\n\
2023 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2024or via the attributes si_pid, si_uid, and so on.\n\
2025\n\
2026See os.waitid for more information.");
2027
2028static PyStructSequence_Field waitid_result_fields[] = {
2029 {"si_pid", },
2030 {"si_uid", },
2031 {"si_signo", },
2032 {"si_status", },
2033 {"si_code", },
2034 {0}
2035};
2036
2037static PyStructSequence_Desc waitid_result_desc = {
2038 "waitid_result", /* name */
2039 waitid_result__doc__, /* doc */
2040 waitid_result_fields,
2041 5
2042};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002043static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02002044#endif
2045
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002046static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002047static PyTypeObject* StatResultType;
2048static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07002049#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002050static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002051#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002052static newfunc structseq_new;
2053
2054static PyObject *
2055statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2056{
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 PyStructSequence *result;
2058 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002059
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 result = (PyStructSequence*)structseq_new(type, args, kwds);
2061 if (!result)
2062 return NULL;
2063 /* If we have been initialized from a tuple,
2064 st_?time might be set to None. Initialize it
2065 from the int slots. */
2066 for (i = 7; i <= 9; i++) {
2067 if (result->ob_item[i+3] == Py_None) {
2068 Py_DECREF(Py_None);
2069 Py_INCREF(result->ob_item[i]);
2070 result->ob_item[i+3] = result->ob_item[i];
2071 }
2072 }
2073 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002074}
2075
2076
Larry Hastings6fe20b32012-04-19 15:07:49 -07002077static PyObject *billion = NULL;
2078
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002079static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002080fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002081{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002082 PyObject *s = _PyLong_FromTime_t(sec);
2083 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2084 PyObject *s_in_ns = NULL;
2085 PyObject *ns_total = NULL;
2086 PyObject *float_s = NULL;
2087
2088 if (!(s && ns_fractional))
2089 goto exit;
2090
2091 s_in_ns = PyNumber_Multiply(s, billion);
2092 if (!s_in_ns)
2093 goto exit;
2094
2095 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2096 if (!ns_total)
2097 goto exit;
2098
Victor Stinner01b5aab2017-10-24 02:02:00 -07002099 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2100 if (!float_s) {
2101 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002102 }
2103
2104 PyStructSequence_SET_ITEM(v, index, s);
2105 PyStructSequence_SET_ITEM(v, index+3, float_s);
2106 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2107 s = NULL;
2108 float_s = NULL;
2109 ns_total = NULL;
2110exit:
2111 Py_XDECREF(s);
2112 Py_XDECREF(ns_fractional);
2113 Py_XDECREF(s_in_ns);
2114 Py_XDECREF(ns_total);
2115 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002116}
2117
Tim Peters5aa91602002-01-30 05:46:57 +00002118/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002119 (used by posix_stat() and posix_fstat()) */
2120static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002121_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002122{
Victor Stinner8c62be82010-05-06 00:08:46 +00002123 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002124 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 if (v == NULL)
2126 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002127
Victor Stinner8c62be82010-05-06 00:08:46 +00002128 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002129 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002130 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002131#ifdef MS_WINDOWS
2132 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002133#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002134 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002135#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002137#if defined(MS_WINDOWS)
2138 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2139 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2140#else
2141 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2142 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2143#endif
xdegaye50e86032017-05-22 11:15:08 +02002144 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2145 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002146
Martin v. Löwis14694662006-02-03 12:54:16 +00002147#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 ansec = st->st_atim.tv_nsec;
2149 mnsec = st->st_mtim.tv_nsec;
2150 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002151#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002152 ansec = st->st_atimespec.tv_nsec;
2153 mnsec = st->st_mtimespec.tv_nsec;
2154 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002155#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002156 ansec = st->st_atime_nsec;
2157 mnsec = st->st_mtime_nsec;
2158 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002161#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002162 fill_time(v, 7, st->st_atime, ansec);
2163 fill_time(v, 8, st->st_mtime, mnsec);
2164 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002165
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002166#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2168 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002169#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002170#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2172 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002173#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002174#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2176 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002177#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002178#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002179 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2180 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002181#endif
2182#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002184 PyObject *val;
2185 unsigned long bsec,bnsec;
2186 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002187#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002188 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002189#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002190 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002191#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002192 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002193 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2194 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002196#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002197#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2199 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002200#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002201#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2202 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2203 PyLong_FromUnsignedLong(st->st_file_attributes));
2204#endif
jcea6c51d512018-01-28 14:00:08 +01002205#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2206 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2207 PyUnicode_FromString(st->st_fstype));
2208#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002209#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2210 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2211 PyLong_FromUnsignedLong(st->st_reparse_tag));
2212#endif
Fred Drake699f3522000-06-29 21:12:41 +00002213
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 if (PyErr_Occurred()) {
2215 Py_DECREF(v);
2216 return NULL;
2217 }
Fred Drake699f3522000-06-29 21:12:41 +00002218
Victor Stinner8c62be82010-05-06 00:08:46 +00002219 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002220}
2221
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002222/* POSIX methods */
2223
Guido van Rossum94f6f721999-01-06 18:42:14 +00002224
2225static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002226posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002227 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002228{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002229 STRUCT_STAT st;
2230 int result;
2231
2232#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2233 if (follow_symlinks_specified(function_name, follow_symlinks))
2234 return NULL;
2235#endif
2236
2237 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2238 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2239 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2240 return NULL;
2241
2242 Py_BEGIN_ALLOW_THREADS
2243 if (path->fd != -1)
2244 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002245#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002246 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002247 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002248 else
Steve Dowercc16be82016-09-08 10:35:16 -07002249 result = win32_lstat(path->wide, &st);
2250#else
2251 else
2252#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002253 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2254 result = LSTAT(path->narrow, &st);
2255 else
Steve Dowercc16be82016-09-08 10:35:16 -07002256#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002257#ifdef HAVE_FSTATAT
2258 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2259 result = fstatat(dir_fd, path->narrow, &st,
2260 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2261 else
Steve Dowercc16be82016-09-08 10:35:16 -07002262#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002263 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002264#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002265 Py_END_ALLOW_THREADS
2266
Victor Stinner292c8352012-10-30 02:17:38 +01002267 if (result != 0) {
2268 return path_error(path);
2269 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002270
2271 return _pystat_fromstructstat(&st);
2272}
2273
Larry Hastings2f936352014-08-05 14:04:04 +10002274/*[python input]
2275
2276for s in """
2277
2278FACCESSAT
2279FCHMODAT
2280FCHOWNAT
2281FSTATAT
2282LINKAT
2283MKDIRAT
2284MKFIFOAT
2285MKNODAT
2286OPENAT
2287READLINKAT
2288SYMLINKAT
2289UNLINKAT
2290
2291""".strip().split():
2292 s = s.strip()
2293 print("""
2294#ifdef HAVE_{s}
2295 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002296#else
Larry Hastings2f936352014-08-05 14:04:04 +10002297 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002298#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002299""".rstrip().format(s=s))
2300
2301for s in """
2302
2303FCHDIR
2304FCHMOD
2305FCHOWN
2306FDOPENDIR
2307FEXECVE
2308FPATHCONF
2309FSTATVFS
2310FTRUNCATE
2311
2312""".strip().split():
2313 s = s.strip()
2314 print("""
2315#ifdef HAVE_{s}
2316 #define PATH_HAVE_{s} 1
2317#else
2318 #define PATH_HAVE_{s} 0
2319#endif
2320
2321""".rstrip().format(s=s))
2322[python start generated code]*/
2323
2324#ifdef HAVE_FACCESSAT
2325 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2326#else
2327 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2328#endif
2329
2330#ifdef HAVE_FCHMODAT
2331 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2332#else
2333 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2334#endif
2335
2336#ifdef HAVE_FCHOWNAT
2337 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2338#else
2339 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2340#endif
2341
2342#ifdef HAVE_FSTATAT
2343 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2344#else
2345 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2346#endif
2347
2348#ifdef HAVE_LINKAT
2349 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2350#else
2351 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2352#endif
2353
2354#ifdef HAVE_MKDIRAT
2355 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2356#else
2357 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2358#endif
2359
2360#ifdef HAVE_MKFIFOAT
2361 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2362#else
2363 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2364#endif
2365
2366#ifdef HAVE_MKNODAT
2367 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2368#else
2369 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2370#endif
2371
2372#ifdef HAVE_OPENAT
2373 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2374#else
2375 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2376#endif
2377
2378#ifdef HAVE_READLINKAT
2379 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2380#else
2381 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2382#endif
2383
2384#ifdef HAVE_SYMLINKAT
2385 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2386#else
2387 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2388#endif
2389
2390#ifdef HAVE_UNLINKAT
2391 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2392#else
2393 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2394#endif
2395
2396#ifdef HAVE_FCHDIR
2397 #define PATH_HAVE_FCHDIR 1
2398#else
2399 #define PATH_HAVE_FCHDIR 0
2400#endif
2401
2402#ifdef HAVE_FCHMOD
2403 #define PATH_HAVE_FCHMOD 1
2404#else
2405 #define PATH_HAVE_FCHMOD 0
2406#endif
2407
2408#ifdef HAVE_FCHOWN
2409 #define PATH_HAVE_FCHOWN 1
2410#else
2411 #define PATH_HAVE_FCHOWN 0
2412#endif
2413
2414#ifdef HAVE_FDOPENDIR
2415 #define PATH_HAVE_FDOPENDIR 1
2416#else
2417 #define PATH_HAVE_FDOPENDIR 0
2418#endif
2419
2420#ifdef HAVE_FEXECVE
2421 #define PATH_HAVE_FEXECVE 1
2422#else
2423 #define PATH_HAVE_FEXECVE 0
2424#endif
2425
2426#ifdef HAVE_FPATHCONF
2427 #define PATH_HAVE_FPATHCONF 1
2428#else
2429 #define PATH_HAVE_FPATHCONF 0
2430#endif
2431
2432#ifdef HAVE_FSTATVFS
2433 #define PATH_HAVE_FSTATVFS 1
2434#else
2435 #define PATH_HAVE_FSTATVFS 0
2436#endif
2437
2438#ifdef HAVE_FTRUNCATE
2439 #define PATH_HAVE_FTRUNCATE 1
2440#else
2441 #define PATH_HAVE_FTRUNCATE 0
2442#endif
2443/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002444
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002445#ifdef MS_WINDOWS
2446 #undef PATH_HAVE_FTRUNCATE
2447 #define PATH_HAVE_FTRUNCATE 1
2448#endif
Larry Hastings31826802013-10-19 00:09:25 -07002449
Larry Hastings61272b72014-01-07 12:41:53 -08002450/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002451
2452class path_t_converter(CConverter):
2453
2454 type = "path_t"
2455 impl_by_reference = True
2456 parse_by_reference = True
2457
2458 converter = 'path_converter'
2459
2460 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002461 # right now path_t doesn't support default values.
2462 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002463 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002464 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002465
Larry Hastings2f936352014-08-05 14:04:04 +10002466 if self.c_default not in (None, 'Py_None'):
2467 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002468
2469 self.nullable = nullable
2470 self.allow_fd = allow_fd
2471
Larry Hastings7726ac92014-01-31 22:03:12 -08002472 def pre_render(self):
2473 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002474 if isinstance(value, str):
2475 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002476 return str(int(bool(value)))
2477
2478 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002479 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002480 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002481 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002482 strify(self.nullable),
2483 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002484 )
2485
2486 def cleanup(self):
2487 return "path_cleanup(&" + self.name + ");\n"
2488
2489
2490class dir_fd_converter(CConverter):
2491 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002492
Larry Hastings2f936352014-08-05 14:04:04 +10002493 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002494 if self.default in (unspecified, None):
2495 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002496 if isinstance(requires, str):
2497 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2498 else:
2499 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002500
Larry Hastings2f936352014-08-05 14:04:04 +10002501class fildes_converter(CConverter):
2502 type = 'int'
2503 converter = 'fildes_converter'
2504
2505class uid_t_converter(CConverter):
2506 type = "uid_t"
2507 converter = '_Py_Uid_Converter'
2508
2509class gid_t_converter(CConverter):
2510 type = "gid_t"
2511 converter = '_Py_Gid_Converter'
2512
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002513class dev_t_converter(CConverter):
2514 type = 'dev_t'
2515 converter = '_Py_Dev_Converter'
2516
2517class dev_t_return_converter(unsigned_long_return_converter):
2518 type = 'dev_t'
2519 conversion_fn = '_PyLong_FromDev'
2520 unsigned_cast = '(dev_t)'
2521
Larry Hastings2f936352014-08-05 14:04:04 +10002522class FSConverter_converter(CConverter):
2523 type = 'PyObject *'
2524 converter = 'PyUnicode_FSConverter'
2525 def converter_init(self):
2526 if self.default is not unspecified:
2527 fail("FSConverter_converter does not support default values")
2528 self.c_default = 'NULL'
2529
2530 def cleanup(self):
2531 return "Py_XDECREF(" + self.name + ");\n"
2532
2533class pid_t_converter(CConverter):
2534 type = 'pid_t'
2535 format_unit = '" _Py_PARSE_PID "'
2536
2537class idtype_t_converter(int_converter):
2538 type = 'idtype_t'
2539
2540class id_t_converter(CConverter):
2541 type = 'id_t'
2542 format_unit = '" _Py_PARSE_PID "'
2543
Benjamin Petersonca470632016-09-06 13:47:26 -07002544class intptr_t_converter(CConverter):
2545 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002546 format_unit = '" _Py_PARSE_INTPTR "'
2547
2548class Py_off_t_converter(CConverter):
2549 type = 'Py_off_t'
2550 converter = 'Py_off_t_converter'
2551
2552class Py_off_t_return_converter(long_return_converter):
2553 type = 'Py_off_t'
2554 conversion_fn = 'PyLong_FromPy_off_t'
2555
2556class path_confname_converter(CConverter):
2557 type="int"
2558 converter="conv_path_confname"
2559
2560class confstr_confname_converter(path_confname_converter):
2561 converter='conv_confstr_confname'
2562
2563class sysconf_confname_converter(path_confname_converter):
2564 converter="conv_sysconf_confname"
2565
2566class sched_param_converter(CConverter):
2567 type = 'struct sched_param'
2568 converter = 'convert_sched_param'
2569 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002570
Larry Hastings61272b72014-01-07 12:41:53 -08002571[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002572/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002573
Larry Hastings61272b72014-01-07 12:41:53 -08002574/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002575
Larry Hastings2a727912014-01-16 11:32:01 -08002576os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002577
2578 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002579 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002580 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002581
2582 *
2583
Larry Hastings2f936352014-08-05 14:04:04 +10002584 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002585 If not None, it should be a file descriptor open to a directory,
2586 and path should be a relative string; path will then be relative to
2587 that directory.
2588
2589 follow_symlinks: bool = True
2590 If False, and the last element of the path is a symbolic link,
2591 stat will examine the symbolic link itself instead of the file
2592 the link points to.
2593
2594Perform a stat system call on the given path.
2595
2596dir_fd and follow_symlinks may not be implemented
2597 on your platform. If they are unavailable, using them will raise a
2598 NotImplementedError.
2599
2600It's an error to use dir_fd or follow_symlinks when specifying path as
2601 an open file descriptor.
2602
Larry Hastings61272b72014-01-07 12:41:53 -08002603[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002604
Larry Hastings31826802013-10-19 00:09:25 -07002605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002606os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002607/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002608{
2609 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2610}
2611
Larry Hastings2f936352014-08-05 14:04:04 +10002612
2613/*[clinic input]
2614os.lstat
2615
2616 path : path_t
2617
2618 *
2619
2620 dir_fd : dir_fd(requires='fstatat') = None
2621
2622Perform a stat system call on the given path, without following symbolic links.
2623
2624Like stat(), but do not follow symbolic links.
2625Equivalent to stat(path, follow_symlinks=False).
2626[clinic start generated code]*/
2627
Larry Hastings2f936352014-08-05 14:04:04 +10002628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002629os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2630/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002631{
2632 int follow_symlinks = 0;
2633 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2634}
Larry Hastings31826802013-10-19 00:09:25 -07002635
Larry Hastings2f936352014-08-05 14:04:04 +10002636
Larry Hastings61272b72014-01-07 12:41:53 -08002637/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002638os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002639
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002640 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002641 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002642
2643 mode: int
2644 Operating-system mode bitfield. Can be F_OK to test existence,
2645 or the inclusive-OR of R_OK, W_OK, and X_OK.
2646
2647 *
2648
Larry Hastings2f936352014-08-05 14:04:04 +10002649 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002650 If not None, it should be a file descriptor open to a directory,
2651 and path should be relative; path will then be relative to that
2652 directory.
2653
2654 effective_ids: bool = False
2655 If True, access will use the effective uid/gid instead of
2656 the real uid/gid.
2657
2658 follow_symlinks: bool = True
2659 If False, and the last element of the path is a symbolic link,
2660 access will examine the symbolic link itself instead of the file
2661 the link points to.
2662
2663Use the real uid/gid to test for access to a path.
2664
2665{parameters}
2666dir_fd, effective_ids, and follow_symlinks may not be implemented
2667 on your platform. If they are unavailable, using them will raise a
2668 NotImplementedError.
2669
2670Note that most operations will use the effective uid/gid, therefore this
2671 routine can be used in a suid/sgid environment to test if the invoking user
2672 has the specified access to the path.
2673
Larry Hastings61272b72014-01-07 12:41:53 -08002674[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002675
Larry Hastings2f936352014-08-05 14:04:04 +10002676static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002677os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002678 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002679/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002680{
Larry Hastings2f936352014-08-05 14:04:04 +10002681 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002682
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002683#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002684 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002685#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002687#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002688
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689#ifndef HAVE_FACCESSAT
2690 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002691 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692
2693 if (effective_ids) {
2694 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002695 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002696 }
2697#endif
2698
2699#ifdef MS_WINDOWS
2700 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002701 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702 Py_END_ALLOW_THREADS
2703
2704 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002705 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002706 * * we didn't get a -1, and
2707 * * write access wasn't requested,
2708 * * or the file isn't read-only,
2709 * * or it's a directory.
2710 * (Directories cannot be read-only on Windows.)
2711 */
Larry Hastings2f936352014-08-05 14:04:04 +10002712 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002713 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002714 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002715 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716#else
2717
2718 Py_BEGIN_ALLOW_THREADS
2719#ifdef HAVE_FACCESSAT
2720 if ((dir_fd != DEFAULT_DIR_FD) ||
2721 effective_ids ||
2722 !follow_symlinks) {
2723 int flags = 0;
2724 if (!follow_symlinks)
2725 flags |= AT_SYMLINK_NOFOLLOW;
2726 if (effective_ids)
2727 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002728 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 }
2730 else
2731#endif
Larry Hastings31826802013-10-19 00:09:25 -07002732 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002734 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735#endif
2736
Larry Hastings9cf065c2012-06-22 16:30:09 -07002737 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002738}
2739
Guido van Rossumd371ff11999-01-25 16:12:23 +00002740#ifndef F_OK
2741#define F_OK 0
2742#endif
2743#ifndef R_OK
2744#define R_OK 4
2745#endif
2746#ifndef W_OK
2747#define W_OK 2
2748#endif
2749#ifndef X_OK
2750#define X_OK 1
2751#endif
2752
Larry Hastings31826802013-10-19 00:09:25 -07002753
Guido van Rossumd371ff11999-01-25 16:12:23 +00002754#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002755/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002756os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002757
2758 fd: int
2759 Integer file descriptor handle.
2760
2761 /
2762
2763Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002764[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002765
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002766static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002767os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002768/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002769{
2770 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002771
Larry Hastings31826802013-10-19 00:09:25 -07002772 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002773 if (ret == NULL) {
2774 return posix_error();
2775 }
2776 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002777}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002778#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002779
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002780#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002781/*[clinic input]
2782os.ctermid
2783
2784Return the name of the controlling terminal for this process.
2785[clinic start generated code]*/
2786
Larry Hastings2f936352014-08-05 14:04:04 +10002787static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002788os_ctermid_impl(PyObject *module)
2789/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002790{
Victor Stinner8c62be82010-05-06 00:08:46 +00002791 char *ret;
2792 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002793
Greg Wardb48bc172000-03-01 21:51:56 +00002794#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002795 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002796#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002797 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002798#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 if (ret == NULL)
2800 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002801 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002802}
Larry Hastings2f936352014-08-05 14:04:04 +10002803#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002804
Larry Hastings2f936352014-08-05 14:04:04 +10002805
2806/*[clinic input]
2807os.chdir
2808
2809 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2810
2811Change the current working directory to the specified path.
2812
2813path may always be specified as a string.
2814On some platforms, path may also be specified as an open file descriptor.
2815 If this functionality is unavailable, using it raises an exception.
2816[clinic start generated code]*/
2817
Larry Hastings2f936352014-08-05 14:04:04 +10002818static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002819os_chdir_impl(PyObject *module, path_t *path)
2820/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002821{
2822 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002823
2824 Py_BEGIN_ALLOW_THREADS
2825#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002826 /* on unix, success = 0, on windows, success = !0 */
2827 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828#else
2829#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002830 if (path->fd != -1)
2831 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832 else
2833#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002834 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835#endif
2836 Py_END_ALLOW_THREADS
2837
2838 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002839 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840 }
2841
Larry Hastings2f936352014-08-05 14:04:04 +10002842 Py_RETURN_NONE;
2843}
2844
2845
2846#ifdef HAVE_FCHDIR
2847/*[clinic input]
2848os.fchdir
2849
2850 fd: fildes
2851
2852Change to the directory of the given file descriptor.
2853
2854fd must be opened on a directory, not a file.
2855Equivalent to os.chdir(fd).
2856
2857[clinic start generated code]*/
2858
Fred Drake4d1e64b2002-04-15 19:40:07 +00002859static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002860os_fchdir_impl(PyObject *module, int fd)
2861/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002862{
Larry Hastings2f936352014-08-05 14:04:04 +10002863 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002864}
2865#endif /* HAVE_FCHDIR */
2866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002867
Larry Hastings2f936352014-08-05 14:04:04 +10002868/*[clinic input]
2869os.chmod
2870
2871 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002872 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002873 On some platforms, path may also be specified as an open file descriptor.
2874 If this functionality is unavailable, using it raises an exception.
2875
2876 mode: int
2877 Operating-system mode bitfield.
2878
2879 *
2880
2881 dir_fd : dir_fd(requires='fchmodat') = None
2882 If not None, it should be a file descriptor open to a directory,
2883 and path should be relative; path will then be relative to that
2884 directory.
2885
2886 follow_symlinks: bool = True
2887 If False, and the last element of the path is a symbolic link,
2888 chmod will modify the symbolic link itself instead of the file
2889 the link points to.
2890
2891Change the access permissions of a file.
2892
2893It is an error to use dir_fd or follow_symlinks when specifying path as
2894 an open file descriptor.
2895dir_fd and follow_symlinks may not be implemented on your platform.
2896 If they are unavailable, using them will raise a NotImplementedError.
2897
2898[clinic start generated code]*/
2899
Larry Hastings2f936352014-08-05 14:04:04 +10002900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002901os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002902 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002903/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002904{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002905 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002906
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002907#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002908 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002910
Larry Hastings9cf065c2012-06-22 16:30:09 -07002911#ifdef HAVE_FCHMODAT
2912 int fchmodat_nofollow_unsupported = 0;
2913#endif
2914
Larry Hastings9cf065c2012-06-22 16:30:09 -07002915#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2916 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002917 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002918#endif
2919
2920#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002921 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002922 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002923 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002924 result = 0;
2925 else {
2926 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 attr &= ~FILE_ATTRIBUTE_READONLY;
2928 else
2929 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002930 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002931 }
2932 Py_END_ALLOW_THREADS
2933
2934 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002935 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002936 }
2937#else /* MS_WINDOWS */
2938 Py_BEGIN_ALLOW_THREADS
2939#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002940 if (path->fd != -1)
2941 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002942 else
2943#endif
2944#ifdef HAVE_LCHMOD
2945 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002946 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002947 else
2948#endif
2949#ifdef HAVE_FCHMODAT
2950 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2951 /*
2952 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2953 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002954 * and then says it isn't implemented yet.
2955 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956 *
2957 * Once it is supported, os.chmod will automatically
2958 * support dir_fd and follow_symlinks=False. (Hopefully.)
2959 * Until then, we need to be careful what exception we raise.
2960 */
Larry Hastings2f936352014-08-05 14:04:04 +10002961 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2963 /*
2964 * But wait! We can't throw the exception without allowing threads,
2965 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2966 */
2967 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002968 result &&
2969 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2970 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 }
2972 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002973#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002974 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975 Py_END_ALLOW_THREADS
2976
2977 if (result) {
2978#ifdef HAVE_FCHMODAT
2979 if (fchmodat_nofollow_unsupported) {
2980 if (dir_fd != DEFAULT_DIR_FD)
2981 dir_fd_and_follow_symlinks_invalid("chmod",
2982 dir_fd, follow_symlinks);
2983 else
2984 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002985 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986 }
2987 else
2988#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002989 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002990 }
2991#endif
2992
Larry Hastings2f936352014-08-05 14:04:04 +10002993 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002994}
2995
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996
Christian Heimes4e30a842007-11-30 22:12:06 +00002997#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002998/*[clinic input]
2999os.fchmod
3000
3001 fd: int
3002 mode: int
3003
3004Change the access permissions of the file given by file descriptor fd.
3005
3006Equivalent to os.chmod(fd, mode).
3007[clinic start generated code]*/
3008
Larry Hastings2f936352014-08-05 14:04:04 +10003009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003010os_fchmod_impl(PyObject *module, int fd, int mode)
3011/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003012{
3013 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003014 int async_err = 0;
3015
3016 do {
3017 Py_BEGIN_ALLOW_THREADS
3018 res = fchmod(fd, mode);
3019 Py_END_ALLOW_THREADS
3020 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3021 if (res != 0)
3022 return (!async_err) ? posix_error() : NULL;
3023
Victor Stinner8c62be82010-05-06 00:08:46 +00003024 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003025}
3026#endif /* HAVE_FCHMOD */
3027
Larry Hastings2f936352014-08-05 14:04:04 +10003028
Christian Heimes4e30a842007-11-30 22:12:06 +00003029#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003030/*[clinic input]
3031os.lchmod
3032
3033 path: path_t
3034 mode: int
3035
3036Change the access permissions of a file, without following symbolic links.
3037
3038If path is a symlink, this affects the link itself rather than the target.
3039Equivalent to chmod(path, mode, follow_symlinks=False)."
3040[clinic start generated code]*/
3041
Larry Hastings2f936352014-08-05 14:04:04 +10003042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003043os_lchmod_impl(PyObject *module, path_t *path, int mode)
3044/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003045{
Victor Stinner8c62be82010-05-06 00:08:46 +00003046 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003047 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003048 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003049 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003050 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003051 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003052 return NULL;
3053 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003054 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003055}
3056#endif /* HAVE_LCHMOD */
3057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003058
Thomas Wouterscf297e42007-02-23 15:07:44 +00003059#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003060/*[clinic input]
3061os.chflags
3062
3063 path: path_t
3064 flags: unsigned_long(bitwise=True)
3065 follow_symlinks: bool=True
3066
3067Set file flags.
3068
3069If follow_symlinks is False, and the last element of the path is a symbolic
3070 link, chflags will change flags on the symbolic link itself instead of the
3071 file the link points to.
3072follow_symlinks may not be implemented on your platform. If it is
3073unavailable, using it will raise a NotImplementedError.
3074
3075[clinic start generated code]*/
3076
Larry Hastings2f936352014-08-05 14:04:04 +10003077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003078os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003079 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003080/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003081{
3082 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003083
3084#ifndef HAVE_LCHFLAGS
3085 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003086 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087#endif
3088
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090#ifdef HAVE_LCHFLAGS
3091 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003092 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003093 else
3094#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003095 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003096 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097
Larry Hastings2f936352014-08-05 14:04:04 +10003098 if (result)
3099 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003100
Larry Hastings2f936352014-08-05 14:04:04 +10003101 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003102}
3103#endif /* HAVE_CHFLAGS */
3104
Larry Hastings2f936352014-08-05 14:04:04 +10003105
Thomas Wouterscf297e42007-02-23 15:07:44 +00003106#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003107/*[clinic input]
3108os.lchflags
3109
3110 path: path_t
3111 flags: unsigned_long(bitwise=True)
3112
3113Set file flags.
3114
3115This function will not follow symbolic links.
3116Equivalent to chflags(path, flags, follow_symlinks=False).
3117[clinic start generated code]*/
3118
Larry Hastings2f936352014-08-05 14:04:04 +10003119static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003120os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3121/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003122{
Victor Stinner8c62be82010-05-06 00:08:46 +00003123 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003125 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003126 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003127 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003128 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003129 }
Victor Stinner292c8352012-10-30 02:17:38 +01003130 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003131}
3132#endif /* HAVE_LCHFLAGS */
3133
Larry Hastings2f936352014-08-05 14:04:04 +10003134
Martin v. Löwis244edc82001-10-04 22:44:26 +00003135#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003136/*[clinic input]
3137os.chroot
3138 path: path_t
3139
3140Change root directory to path.
3141
3142[clinic start generated code]*/
3143
Larry Hastings2f936352014-08-05 14:04:04 +10003144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003145os_chroot_impl(PyObject *module, path_t *path)
3146/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003147{
3148 int res;
3149 Py_BEGIN_ALLOW_THREADS
3150 res = chroot(path->narrow);
3151 Py_END_ALLOW_THREADS
3152 if (res < 0)
3153 return path_error(path);
3154 Py_RETURN_NONE;
3155}
3156#endif /* HAVE_CHROOT */
3157
Martin v. Löwis244edc82001-10-04 22:44:26 +00003158
Guido van Rossum21142a01999-01-08 21:05:37 +00003159#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003160/*[clinic input]
3161os.fsync
3162
3163 fd: fildes
3164
3165Force write of fd to disk.
3166[clinic start generated code]*/
3167
Larry Hastings2f936352014-08-05 14:04:04 +10003168static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003169os_fsync_impl(PyObject *module, int fd)
3170/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003171{
3172 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003173}
3174#endif /* HAVE_FSYNC */
3175
Larry Hastings2f936352014-08-05 14:04:04 +10003176
Ross Lagerwall7807c352011-03-17 20:20:30 +02003177#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003178/*[clinic input]
3179os.sync
3180
3181Force write of everything to disk.
3182[clinic start generated code]*/
3183
Larry Hastings2f936352014-08-05 14:04:04 +10003184static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003185os_sync_impl(PyObject *module)
3186/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003187{
3188 Py_BEGIN_ALLOW_THREADS
3189 sync();
3190 Py_END_ALLOW_THREADS
3191 Py_RETURN_NONE;
3192}
Larry Hastings2f936352014-08-05 14:04:04 +10003193#endif /* HAVE_SYNC */
3194
Ross Lagerwall7807c352011-03-17 20:20:30 +02003195
Guido van Rossum21142a01999-01-08 21:05:37 +00003196#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003197#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003198extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3199#endif
3200
Larry Hastings2f936352014-08-05 14:04:04 +10003201/*[clinic input]
3202os.fdatasync
3203
3204 fd: fildes
3205
3206Force write of fd to disk without forcing update of metadata.
3207[clinic start generated code]*/
3208
Larry Hastings2f936352014-08-05 14:04:04 +10003209static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003210os_fdatasync_impl(PyObject *module, int fd)
3211/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003212{
3213 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003214}
3215#endif /* HAVE_FDATASYNC */
3216
3217
Fredrik Lundh10723342000-07-10 16:38:09 +00003218#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003219/*[clinic input]
3220os.chown
3221
3222 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003223 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003224
3225 uid: uid_t
3226
3227 gid: gid_t
3228
3229 *
3230
3231 dir_fd : dir_fd(requires='fchownat') = None
3232 If not None, it should be a file descriptor open to a directory,
3233 and path should be relative; path will then be relative to that
3234 directory.
3235
3236 follow_symlinks: bool = True
3237 If False, and the last element of the path is a symbolic link,
3238 stat will examine the symbolic link itself instead of the file
3239 the link points to.
3240
3241Change the owner and group id of path to the numeric uid and gid.\
3242
3243path may always be specified as a string.
3244On some platforms, path may also be specified as an open file descriptor.
3245 If this functionality is unavailable, using it raises an exception.
3246If dir_fd is not None, it should be a file descriptor open to a directory,
3247 and path should be relative; path will then be relative to that directory.
3248If follow_symlinks is False, and the last element of the path is a symbolic
3249 link, chown will modify the symbolic link itself instead of the file the
3250 link points to.
3251It is an error to use dir_fd or follow_symlinks when specifying path as
3252 an open file descriptor.
3253dir_fd and follow_symlinks may not be implemented on your platform.
3254 If they are unavailable, using them will raise a NotImplementedError.
3255
3256[clinic start generated code]*/
3257
Larry Hastings2f936352014-08-05 14:04:04 +10003258static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003259os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003260 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003261/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003262{
3263 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003264
3265#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3266 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003267 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003268#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003269 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3270 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3271 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272
3273#ifdef __APPLE__
3274 /*
3275 * This is for Mac OS X 10.3, which doesn't have lchown.
3276 * (But we still have an lchown symbol because of weak-linking.)
3277 * It doesn't have fchownat either. So there's no possibility
3278 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003279 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003280 if ((!follow_symlinks) && (lchown == NULL)) {
3281 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003282 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003283 }
3284#endif
3285
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003287#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003288 if (path->fd != -1)
3289 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003290 else
3291#endif
3292#ifdef HAVE_LCHOWN
3293 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003294 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003295 else
3296#endif
3297#ifdef HAVE_FCHOWNAT
3298 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003299 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3301 else
3302#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003303 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003304 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003305
Larry Hastings2f936352014-08-05 14:04:04 +10003306 if (result)
3307 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003308
Larry Hastings2f936352014-08-05 14:04:04 +10003309 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003310}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003311#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003312
Larry Hastings2f936352014-08-05 14:04:04 +10003313
Christian Heimes4e30a842007-11-30 22:12:06 +00003314#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003315/*[clinic input]
3316os.fchown
3317
3318 fd: int
3319 uid: uid_t
3320 gid: gid_t
3321
3322Change the owner and group id of the file specified by file descriptor.
3323
3324Equivalent to os.chown(fd, uid, gid).
3325
3326[clinic start generated code]*/
3327
Larry Hastings2f936352014-08-05 14:04:04 +10003328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003329os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3330/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003331{
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003333 int async_err = 0;
3334
3335 do {
3336 Py_BEGIN_ALLOW_THREADS
3337 res = fchown(fd, uid, gid);
3338 Py_END_ALLOW_THREADS
3339 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3340 if (res != 0)
3341 return (!async_err) ? posix_error() : NULL;
3342
Victor Stinner8c62be82010-05-06 00:08:46 +00003343 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003344}
3345#endif /* HAVE_FCHOWN */
3346
Larry Hastings2f936352014-08-05 14:04:04 +10003347
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003348#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003349/*[clinic input]
3350os.lchown
3351
3352 path : path_t
3353 uid: uid_t
3354 gid: gid_t
3355
3356Change the owner and group id of path to the numeric uid and gid.
3357
3358This function will not follow symbolic links.
3359Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3360[clinic start generated code]*/
3361
Larry Hastings2f936352014-08-05 14:04:04 +10003362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003363os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3364/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003365{
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003368 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003369 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003370 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003371 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003372 }
Larry Hastings2f936352014-08-05 14:04:04 +10003373 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003374}
3375#endif /* HAVE_LCHOWN */
3376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003377
Barry Warsaw53699e91996-12-10 23:23:01 +00003378static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003379posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003380{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003381#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003382 wchar_t wbuf[MAXPATHLEN];
3383 wchar_t *wbuf2 = wbuf;
3384 DWORD len;
3385
3386 Py_BEGIN_ALLOW_THREADS
3387 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3388 /* If the buffer is large enough, len does not include the
3389 terminating \0. If the buffer is too small, len includes
3390 the space needed for the terminator. */
3391 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003392 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003393 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 }
Victor Stinner689830e2019-06-26 17:31:12 +02003395 else {
3396 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003397 }
Victor Stinner689830e2019-06-26 17:31:12 +02003398 if (wbuf2) {
3399 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 }
Victor Stinner689830e2019-06-26 17:31:12 +02003401 }
3402 Py_END_ALLOW_THREADS
3403
3404 if (!wbuf2) {
3405 PyErr_NoMemory();
3406 return NULL;
3407 }
3408 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003409 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003410 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003411 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003413
Victor Stinner689830e2019-06-26 17:31:12 +02003414 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3415 if (wbuf2 != wbuf) {
3416 PyMem_RawFree(wbuf2);
3417 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003418
Victor Stinner689830e2019-06-26 17:31:12 +02003419 if (use_bytes) {
3420 if (resobj == NULL) {
3421 return NULL;
3422 }
3423 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3424 }
3425
3426 return resobj;
3427#else
3428 const size_t chunk = 1024;
3429
3430 char *buf = NULL;
3431 char *cwd = NULL;
3432 size_t buflen = 0;
3433
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003435 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003436 char *newbuf;
3437 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3438 buflen += chunk;
3439 newbuf = PyMem_RawRealloc(buf, buflen);
3440 }
3441 else {
3442 newbuf = NULL;
3443 }
3444 if (newbuf == NULL) {
3445 PyMem_RawFree(buf);
3446 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003447 break;
3448 }
Victor Stinner689830e2019-06-26 17:31:12 +02003449 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003450
Victor Stinner4403d7d2015-04-25 00:16:10 +02003451 cwd = getcwd(buf, buflen);
3452 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003454
Victor Stinner689830e2019-06-26 17:31:12 +02003455 if (buf == NULL) {
3456 return PyErr_NoMemory();
3457 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003458 if (cwd == NULL) {
3459 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003461 }
3462
Victor Stinner689830e2019-06-26 17:31:12 +02003463 PyObject *obj;
3464 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003465 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003466 }
3467 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003468 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003469 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003470 PyMem_RawFree(buf);
3471
3472 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003473#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003474}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003475
Larry Hastings2f936352014-08-05 14:04:04 +10003476
3477/*[clinic input]
3478os.getcwd
3479
3480Return a unicode string representing the current working directory.
3481[clinic start generated code]*/
3482
Larry Hastings2f936352014-08-05 14:04:04 +10003483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003484os_getcwd_impl(PyObject *module)
3485/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003486{
3487 return posix_getcwd(0);
3488}
3489
Larry Hastings2f936352014-08-05 14:04:04 +10003490
3491/*[clinic input]
3492os.getcwdb
3493
3494Return a bytes string representing the current working directory.
3495[clinic start generated code]*/
3496
Larry Hastings2f936352014-08-05 14:04:04 +10003497static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003498os_getcwdb_impl(PyObject *module)
3499/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003500{
3501 return posix_getcwd(1);
3502}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003503
Larry Hastings2f936352014-08-05 14:04:04 +10003504
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3506#define HAVE_LINK 1
3507#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003508
Guido van Rossumb6775db1994-08-01 11:34:53 +00003509#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003510/*[clinic input]
3511
3512os.link
3513
3514 src : path_t
3515 dst : path_t
3516 *
3517 src_dir_fd : dir_fd = None
3518 dst_dir_fd : dir_fd = None
3519 follow_symlinks: bool = True
3520
3521Create a hard link to a file.
3522
3523If either src_dir_fd or dst_dir_fd is not None, it should be a file
3524 descriptor open to a directory, and the respective path string (src or dst)
3525 should be relative; the path will then be relative to that directory.
3526If follow_symlinks is False, and the last element of src is a symbolic
3527 link, link will create a link to the symbolic link itself instead of the
3528 file the link points to.
3529src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3530 platform. If they are unavailable, using them will raise a
3531 NotImplementedError.
3532[clinic start generated code]*/
3533
Larry Hastings2f936352014-08-05 14:04:04 +10003534static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003535os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003536 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003537/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003538{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003540 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541#else
3542 int result;
3543#endif
3544
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545#ifndef HAVE_LINKAT
3546 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3547 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003548 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 }
3550#endif
3551
Steve Dowercc16be82016-09-08 10:35:16 -07003552#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003553 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 PyErr_SetString(PyExc_NotImplementedError,
3555 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003556 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 }
Steve Dowercc16be82016-09-08 10:35:16 -07003558#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003559
Brian Curtin1b9df392010-11-24 20:24:31 +00003560#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003562 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003564
Larry Hastings2f936352014-08-05 14:04:04 +10003565 if (!result)
3566 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567#else
3568 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003569#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3571 (dst_dir_fd != DEFAULT_DIR_FD) ||
3572 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003573 result = linkat(src_dir_fd, src->narrow,
3574 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3576 else
Steve Dowercc16be82016-09-08 10:35:16 -07003577#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003578 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003580
Larry Hastings2f936352014-08-05 14:04:04 +10003581 if (result)
3582 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003583#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584
Larry Hastings2f936352014-08-05 14:04:04 +10003585 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003586}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587#endif
3588
Brian Curtin1b9df392010-11-24 20:24:31 +00003589
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003590#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003591static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003592_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003593{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 PyObject *v;
3595 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3596 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003597 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003599 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601
Steve Dowercc16be82016-09-08 10:35:16 -07003602 WIN32_FIND_DATAW wFileData;
3603 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003604
Steve Dowercc16be82016-09-08 10:35:16 -07003605 if (!path->wide) { /* Default arg: "." */
3606 po_wchars = L".";
3607 len = 1;
3608 } else {
3609 po_wchars = path->wide;
3610 len = wcslen(path->wide);
3611 }
3612 /* The +5 is so we can append "\\*.*\0" */
3613 wnamebuf = PyMem_New(wchar_t, len + 5);
3614 if (!wnamebuf) {
3615 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 }
Steve Dowercc16be82016-09-08 10:35:16 -07003618 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003620 wchar_t wch = wnamebuf[len-1];
3621 if (wch != SEP && wch != ALTSEP && wch != L':')
3622 wnamebuf[len++] = SEP;
3623 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 }
Steve Dowercc16be82016-09-08 10:35:16 -07003625 if ((list = PyList_New(0)) == NULL) {
3626 goto exit;
3627 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003628 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003629 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003630 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 if (hFindFile == INVALID_HANDLE_VALUE) {
3632 int error = GetLastError();
3633 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 goto exit;
3635 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003636 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 }
3639 do {
3640 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003641 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3642 wcscmp(wFileData.cFileName, L"..") != 0) {
3643 v = PyUnicode_FromWideChar(wFileData.cFileName,
3644 wcslen(wFileData.cFileName));
3645 if (path->narrow && v) {
3646 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3647 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 Py_DECREF(list);
3650 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 break;
3652 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655 Py_DECREF(list);
3656 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 break;
3658 }
3659 Py_DECREF(v);
3660 }
3661 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003662 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 Py_END_ALLOW_THREADS
3664 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3665 it got to the end of the directory. */
3666 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003668 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003669 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 }
3671 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003672
Larry Hastings9cf065c2012-06-22 16:30:09 -07003673exit:
3674 if (hFindFile != INVALID_HANDLE_VALUE) {
3675 if (FindClose(hFindFile) == FALSE) {
3676 if (list != NULL) {
3677 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003678 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 }
3680 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003682 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003683
Larry Hastings9cf065c2012-06-22 16:30:09 -07003684 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003685} /* end of _listdir_windows_no_opendir */
3686
3687#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3688
3689static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003690_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003691{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003692 PyObject *v;
3693 DIR *dirp = NULL;
3694 struct dirent *ep;
3695 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003696#ifdef HAVE_FDOPENDIR
3697 int fd = -1;
3698#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003699
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003701#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003702 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003703 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003704 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003705 if (fd == -1)
3706 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003707
Larry Hastingsfdaea062012-06-25 04:42:23 -07003708 return_str = 1;
3709
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 Py_BEGIN_ALLOW_THREADS
3711 dirp = fdopendir(fd);
3712 Py_END_ALLOW_THREADS
3713 }
3714 else
3715#endif
3716 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003717 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003718 if (path->narrow) {
3719 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003720 /* only return bytes if they specified a bytes-like object */
3721 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003722 }
3723 else {
3724 name = ".";
3725 return_str = 1;
3726 }
3727
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 Py_BEGIN_ALLOW_THREADS
3729 dirp = opendir(name);
3730 Py_END_ALLOW_THREADS
3731 }
3732
3733 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003734 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003735#ifdef HAVE_FDOPENDIR
3736 if (fd != -1) {
3737 Py_BEGIN_ALLOW_THREADS
3738 close(fd);
3739 Py_END_ALLOW_THREADS
3740 }
3741#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003742 goto exit;
3743 }
3744 if ((list = PyList_New(0)) == NULL) {
3745 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003746 }
3747 for (;;) {
3748 errno = 0;
3749 Py_BEGIN_ALLOW_THREADS
3750 ep = readdir(dirp);
3751 Py_END_ALLOW_THREADS
3752 if (ep == NULL) {
3753 if (errno == 0) {
3754 break;
3755 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003756 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003757 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003758 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003759 }
3760 }
3761 if (ep->d_name[0] == '.' &&
3762 (NAMLEN(ep) == 1 ||
3763 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3764 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003765 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003766 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3767 else
3768 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003770 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003771 break;
3772 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003773 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003774 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003775 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003776 break;
3777 }
3778 Py_DECREF(v);
3779 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003780
Larry Hastings9cf065c2012-06-22 16:30:09 -07003781exit:
3782 if (dirp != NULL) {
3783 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003784#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003785 if (fd > -1)
3786 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003787#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003788 closedir(dirp);
3789 Py_END_ALLOW_THREADS
3790 }
3791
Larry Hastings9cf065c2012-06-22 16:30:09 -07003792 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003793} /* end of _posix_listdir */
3794#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003795
Larry Hastings2f936352014-08-05 14:04:04 +10003796
3797/*[clinic input]
3798os.listdir
3799
3800 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3801
3802Return a list containing the names of the files in the directory.
3803
BNMetricsb9427072018-11-02 15:20:19 +00003804path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003805 the filenames returned will also be bytes; in all other circumstances
3806 the filenames returned will be str.
3807If path is None, uses the path='.'.
3808On some platforms, path may also be specified as an open file descriptor;\
3809 the file descriptor must refer to a directory.
3810 If this functionality is unavailable, using it raises NotImplementedError.
3811
3812The list is in arbitrary order. It does not include the special
3813entries '.' and '..' even if they are present in the directory.
3814
3815
3816[clinic start generated code]*/
3817
Larry Hastings2f936352014-08-05 14:04:04 +10003818static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003819os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003820/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003821{
Steve Dower60419a72019-06-24 08:42:54 -07003822 if (PySys_Audit("os.listdir", "O",
3823 path->object ? path->object : Py_None) < 0) {
3824 return NULL;
3825 }
Larry Hastings2f936352014-08-05 14:04:04 +10003826#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3827 return _listdir_windows_no_opendir(path, NULL);
3828#else
3829 return _posix_listdir(path, NULL);
3830#endif
3831}
3832
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003833#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003834/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003835/*[clinic input]
3836os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003837
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003838 path: path_t
3839 /
3840
3841[clinic start generated code]*/
3842
3843static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003844os__getfullpathname_impl(PyObject *module, path_t *path)
3845/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003846{
Victor Stinner3939c322019-06-25 15:02:43 +02003847 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003848
Victor Stinner3939c322019-06-25 15:02:43 +02003849 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
3850 if (_Py_abspath(path->wide, &abspath) < 0) {
3851 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003852 }
Victor Stinner3939c322019-06-25 15:02:43 +02003853 if (abspath == NULL) {
3854 return PyErr_NoMemory();
3855 }
3856
3857 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
3858 PyMem_RawFree(abspath);
3859 if (str == NULL) {
3860 return NULL;
3861 }
3862 if (path->narrow) {
3863 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
3864 }
3865 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10003866}
Brian Curtind40e6f72010-07-08 21:39:08 +00003867
Brian Curtind25aef52011-06-13 15:16:04 -05003868
Larry Hastings2f936352014-08-05 14:04:04 +10003869/*[clinic input]
3870os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003871
Steve Dower23ad6d02018-02-22 10:39:10 -08003872 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003873 /
3874
3875A helper function for samepath on windows.
3876[clinic start generated code]*/
3877
Larry Hastings2f936352014-08-05 14:04:04 +10003878static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003879os__getfinalpathname_impl(PyObject *module, path_t *path)
3880/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003881{
3882 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003883 wchar_t buf[MAXPATHLEN], *target_path = buf;
3884 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003885 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003886 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003887
Steve Dower23ad6d02018-02-22 10:39:10 -08003888 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003889 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003890 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003891 0, /* desired access */
3892 0, /* share mode */
3893 NULL, /* security attributes */
3894 OPEN_EXISTING,
3895 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3896 FILE_FLAG_BACKUP_SEMANTICS,
3897 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003898 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003899
Steve Dower23ad6d02018-02-22 10:39:10 -08003900 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003901 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003902 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003903
3904 /* We have a good handle to the target, use it to determine the
3905 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003906 while (1) {
3907 Py_BEGIN_ALLOW_THREADS
3908 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3909 buf_size, VOLUME_NAME_DOS);
3910 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003911
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003912 if (!result_length) {
3913 result = win32_error_object("GetFinalPathNameByHandleW",
3914 path->object);
3915 goto cleanup;
3916 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003917
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003918 if (result_length < buf_size) {
3919 break;
3920 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003921
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003922 wchar_t *tmp;
3923 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3924 result_length * sizeof(*tmp));
3925 if (!tmp) {
3926 result = PyErr_NoMemory();
3927 goto cleanup;
3928 }
3929
3930 buf_size = result_length;
3931 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003932 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003933
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003934 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07003935 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003936 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07003937 }
Steve Dower23ad6d02018-02-22 10:39:10 -08003938
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003939cleanup:
3940 if (target_path != buf) {
3941 PyMem_Free(target_path);
3942 }
3943 CloseHandle(hFile);
3944 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003945}
Brian Curtin62857742010-09-06 17:07:27 +00003946
Tim Golden6b528062013-08-01 12:44:00 +01003947
Larry Hastings2f936352014-08-05 14:04:04 +10003948/*[clinic input]
3949os._getvolumepathname
3950
Steve Dower23ad6d02018-02-22 10:39:10 -08003951 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003952
3953A helper function for ismount on Win32.
3954[clinic start generated code]*/
3955
Larry Hastings2f936352014-08-05 14:04:04 +10003956static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003957os__getvolumepathname_impl(PyObject *module, path_t *path)
3958/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003959{
3960 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003961 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003962 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003963 BOOL ret;
3964
Tim Golden6b528062013-08-01 12:44:00 +01003965 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003966 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003967
Victor Stinner850a18e2017-10-24 16:53:32 -07003968 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003969 PyErr_SetString(PyExc_OverflowError, "path too long");
3970 return NULL;
3971 }
3972
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003973 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003974 if (mountpath == NULL)
3975 return PyErr_NoMemory();
3976
3977 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003978 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003979 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003980 Py_END_ALLOW_THREADS
3981
3982 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003983 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003984 goto exit;
3985 }
3986 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003987 if (path->narrow)
3988 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003989
3990exit:
3991 PyMem_Free(mountpath);
3992 return result;
3993}
Tim Golden6b528062013-08-01 12:44:00 +01003994
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003995#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003996
Larry Hastings2f936352014-08-05 14:04:04 +10003997
3998/*[clinic input]
3999os.mkdir
4000
4001 path : path_t
4002
4003 mode: int = 0o777
4004
4005 *
4006
4007 dir_fd : dir_fd(requires='mkdirat') = None
4008
4009# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4010
4011Create a directory.
4012
4013If dir_fd is not None, it should be a file descriptor open to a directory,
4014 and path should be relative; path will then be relative to that directory.
4015dir_fd may not be implemented on your platform.
4016 If it is unavailable, using it will raise a NotImplementedError.
4017
4018The mode argument is ignored on Windows.
4019[clinic start generated code]*/
4020
Larry Hastings2f936352014-08-05 14:04:04 +10004021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004022os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4023/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004024{
4025 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004026
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004027#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004028 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004029 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004030 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004031
Larry Hastings2f936352014-08-05 14:04:04 +10004032 if (!result)
4033 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004034#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004035 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004036#if HAVE_MKDIRAT
4037 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004038 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004039 else
4040#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004041#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004042 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004043#else
Larry Hastings2f936352014-08-05 14:04:04 +10004044 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004045#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004047 if (result < 0)
4048 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004049#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004050 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004051}
4052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004053
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004054/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4055#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004056#include <sys/resource.h>
4057#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004058
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004059
4060#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004061/*[clinic input]
4062os.nice
4063
4064 increment: int
4065 /
4066
4067Add increment to the priority of process and return the new priority.
4068[clinic start generated code]*/
4069
Larry Hastings2f936352014-08-05 14:04:04 +10004070static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004071os_nice_impl(PyObject *module, int increment)
4072/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004073{
4074 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004075
Victor Stinner8c62be82010-05-06 00:08:46 +00004076 /* There are two flavours of 'nice': one that returns the new
4077 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004078 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004079 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004080
Victor Stinner8c62be82010-05-06 00:08:46 +00004081 If we are of the nice family that returns the new priority, we
4082 need to clear errno before the call, and check if errno is filled
4083 before calling posix_error() on a returnvalue of -1, because the
4084 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004085
Victor Stinner8c62be82010-05-06 00:08:46 +00004086 errno = 0;
4087 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004088#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004089 if (value == 0)
4090 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004091#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004092 if (value == -1 && errno != 0)
4093 /* either nice() or getpriority() returned an error */
4094 return posix_error();
4095 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004096}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004097#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004098
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004099
4100#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004101/*[clinic input]
4102os.getpriority
4103
4104 which: int
4105 who: int
4106
4107Return program scheduling priority.
4108[clinic start generated code]*/
4109
Larry Hastings2f936352014-08-05 14:04:04 +10004110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004111os_getpriority_impl(PyObject *module, int which, int who)
4112/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004113{
4114 int retval;
4115
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004116 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004117 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004118 if (errno != 0)
4119 return posix_error();
4120 return PyLong_FromLong((long)retval);
4121}
4122#endif /* HAVE_GETPRIORITY */
4123
4124
4125#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004126/*[clinic input]
4127os.setpriority
4128
4129 which: int
4130 who: int
4131 priority: int
4132
4133Set program scheduling priority.
4134[clinic start generated code]*/
4135
Larry Hastings2f936352014-08-05 14:04:04 +10004136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004137os_setpriority_impl(PyObject *module, int which, int who, int priority)
4138/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004139{
4140 int retval;
4141
4142 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004143 if (retval == -1)
4144 return posix_error();
4145 Py_RETURN_NONE;
4146}
4147#endif /* HAVE_SETPRIORITY */
4148
4149
Barry Warsaw53699e91996-12-10 23:23:01 +00004150static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004151internal_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 +00004152{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004153 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004156#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004157 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004158 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004159#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004161#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004162
Larry Hastings9cf065c2012-06-22 16:30:09 -07004163 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4164 (dst_dir_fd != DEFAULT_DIR_FD);
4165#ifndef HAVE_RENAMEAT
4166 if (dir_fd_specified) {
4167 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004168 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004169 }
4170#endif
4171
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172#ifdef MS_WINDOWS
4173 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004174 result = MoveFileExW(src->wide, dst->wide, flags);
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
4180#else
Steve Dowercc16be82016-09-08 10:35:16 -07004181 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4182 PyErr_Format(PyExc_ValueError,
4183 "%s: src and dst must be the same type", function_name);
4184 return NULL;
4185 }
4186
Larry Hastings9cf065c2012-06-22 16:30:09 -07004187 Py_BEGIN_ALLOW_THREADS
4188#ifdef HAVE_RENAMEAT
4189 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004190 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004191 else
4192#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004193 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004194 Py_END_ALLOW_THREADS
4195
Larry Hastings2f936352014-08-05 14:04:04 +10004196 if (result)
4197 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004198#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004199 Py_RETURN_NONE;
4200}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004201
Larry Hastings2f936352014-08-05 14:04:04 +10004202
4203/*[clinic input]
4204os.rename
4205
4206 src : path_t
4207 dst : path_t
4208 *
4209 src_dir_fd : dir_fd = None
4210 dst_dir_fd : dir_fd = None
4211
4212Rename a file or directory.
4213
4214If either src_dir_fd or dst_dir_fd is not None, it should be a file
4215 descriptor open to a directory, and the respective path string (src or dst)
4216 should be relative; the path will then be relative to that directory.
4217src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4218 If they are unavailable, using them will raise a NotImplementedError.
4219[clinic start generated code]*/
4220
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004221static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004222os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004223 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004224/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004225{
Larry Hastings2f936352014-08-05 14:04:04 +10004226 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004227}
4228
Larry Hastings2f936352014-08-05 14:04:04 +10004229
4230/*[clinic input]
4231os.replace = os.rename
4232
4233Rename a file or directory, overwriting the destination.
4234
4235If either src_dir_fd or dst_dir_fd is not None, it should be a file
4236 descriptor open to a directory, and the respective path string (src or dst)
4237 should be relative; the path will then be relative to that directory.
4238src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004239 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004240[clinic start generated code]*/
4241
Larry Hastings2f936352014-08-05 14:04:04 +10004242static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004243os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4244 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004245/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004246{
4247 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4248}
4249
4250
4251/*[clinic input]
4252os.rmdir
4253
4254 path: path_t
4255 *
4256 dir_fd: dir_fd(requires='unlinkat') = None
4257
4258Remove a directory.
4259
4260If dir_fd is not None, it should be a file descriptor open to a directory,
4261 and path should be relative; path will then be relative to that directory.
4262dir_fd may not be implemented on your platform.
4263 If it is unavailable, using it will raise a NotImplementedError.
4264[clinic start generated code]*/
4265
Larry Hastings2f936352014-08-05 14:04:04 +10004266static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004267os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4268/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004269{
4270 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004271
4272 Py_BEGIN_ALLOW_THREADS
4273#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004274 /* Windows, success=1, UNIX, success=0 */
4275 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004276#else
4277#ifdef HAVE_UNLINKAT
4278 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004279 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004280 else
4281#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004282 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004283#endif
4284 Py_END_ALLOW_THREADS
4285
Larry Hastings2f936352014-08-05 14:04:04 +10004286 if (result)
4287 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004288
Larry Hastings2f936352014-08-05 14:04:04 +10004289 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004290}
4291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004292
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004293#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004294#ifdef MS_WINDOWS
4295/*[clinic input]
4296os.system -> long
4297
4298 command: Py_UNICODE
4299
4300Execute the command in a subshell.
4301[clinic start generated code]*/
4302
Larry Hastings2f936352014-08-05 14:04:04 +10004303static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004304os_system_impl(PyObject *module, const Py_UNICODE *command)
4305/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004306{
4307 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004308
4309 if (PySys_Audit("system", "(u)", command) < 0) {
4310 return -1;
4311 }
4312
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004314 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004315 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004316 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004317 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004318 return result;
4319}
4320#else /* MS_WINDOWS */
4321/*[clinic input]
4322os.system -> long
4323
4324 command: FSConverter
4325
4326Execute the command in a subshell.
4327[clinic start generated code]*/
4328
Larry Hastings2f936352014-08-05 14:04:04 +10004329static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004330os_system_impl(PyObject *module, PyObject *command)
4331/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004332{
4333 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004334 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004335
4336 if (PySys_Audit("system", "(O)", command) < 0) {
4337 return -1;
4338 }
4339
Larry Hastings2f936352014-08-05 14:04:04 +10004340 Py_BEGIN_ALLOW_THREADS
4341 result = system(bytes);
4342 Py_END_ALLOW_THREADS
4343 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004344}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004345#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004346#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004348
Larry Hastings2f936352014-08-05 14:04:04 +10004349/*[clinic input]
4350os.umask
4351
4352 mask: int
4353 /
4354
4355Set the current numeric umask and return the previous umask.
4356[clinic start generated code]*/
4357
Larry Hastings2f936352014-08-05 14:04:04 +10004358static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004359os_umask_impl(PyObject *module, int mask)
4360/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004361{
4362 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004363 if (i < 0)
4364 return posix_error();
4365 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004366}
4367
Brian Curtind40e6f72010-07-08 21:39:08 +00004368#ifdef MS_WINDOWS
4369
4370/* override the default DeleteFileW behavior so that directory
4371symlinks can be removed with this function, the same as with
4372Unix symlinks */
4373BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4374{
4375 WIN32_FILE_ATTRIBUTE_DATA info;
4376 WIN32_FIND_DATAW find_data;
4377 HANDLE find_data_handle;
4378 int is_directory = 0;
4379 int is_link = 0;
4380
4381 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4382 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004383
Brian Curtind40e6f72010-07-08 21:39:08 +00004384 /* Get WIN32_FIND_DATA structure for the path to determine if
4385 it is a symlink */
4386 if(is_directory &&
4387 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4388 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4389
4390 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004391 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4392 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4393 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4394 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004395 FindClose(find_data_handle);
4396 }
4397 }
4398 }
4399
4400 if (is_directory && is_link)
4401 return RemoveDirectoryW(lpFileName);
4402
4403 return DeleteFileW(lpFileName);
4404}
4405#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004407
Larry Hastings2f936352014-08-05 14:04:04 +10004408/*[clinic input]
4409os.unlink
4410
4411 path: path_t
4412 *
4413 dir_fd: dir_fd(requires='unlinkat')=None
4414
4415Remove a file (same as remove()).
4416
4417If dir_fd is not None, it should be a file descriptor open to a directory,
4418 and path should be relative; path will then be relative to that directory.
4419dir_fd may not be implemented on your platform.
4420 If it is unavailable, using it will raise a NotImplementedError.
4421
4422[clinic start generated code]*/
4423
Larry Hastings2f936352014-08-05 14:04:04 +10004424static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004425os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4426/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004427{
4428 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004429
4430 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004431 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004433 /* Windows, success=1, UNIX, success=0 */
4434 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004435#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004436#ifdef HAVE_UNLINKAT
4437 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004438 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 else
4440#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004441 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004442#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004443 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 Py_END_ALLOW_THREADS
4445
Larry Hastings2f936352014-08-05 14:04:04 +10004446 if (result)
4447 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004448
Larry Hastings2f936352014-08-05 14:04:04 +10004449 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004450}
4451
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004452
Larry Hastings2f936352014-08-05 14:04:04 +10004453/*[clinic input]
4454os.remove = os.unlink
4455
4456Remove a file (same as unlink()).
4457
4458If dir_fd is not None, it should be a file descriptor open to a directory,
4459 and path should be relative; path will then be relative to that directory.
4460dir_fd may not be implemented on your platform.
4461 If it is unavailable, using it will raise a NotImplementedError.
4462[clinic start generated code]*/
4463
Larry Hastings2f936352014-08-05 14:04:04 +10004464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004465os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4466/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004467{
4468 return os_unlink_impl(module, path, dir_fd);
4469}
4470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004471
Larry Hastings605a62d2012-06-24 04:33:36 -07004472static PyStructSequence_Field uname_result_fields[] = {
4473 {"sysname", "operating system name"},
4474 {"nodename", "name of machine on network (implementation-defined)"},
4475 {"release", "operating system release"},
4476 {"version", "operating system version"},
4477 {"machine", "hardware identifier"},
4478 {NULL}
4479};
4480
4481PyDoc_STRVAR(uname_result__doc__,
4482"uname_result: Result from os.uname().\n\n\
4483This object may be accessed either as a tuple of\n\
4484 (sysname, nodename, release, version, machine),\n\
4485or via the attributes sysname, nodename, release, version, and machine.\n\
4486\n\
4487See os.uname for more information.");
4488
4489static PyStructSequence_Desc uname_result_desc = {
4490 "uname_result", /* name */
4491 uname_result__doc__, /* doc */
4492 uname_result_fields,
4493 5
4494};
4495
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004496static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004497
4498
4499#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004500/*[clinic input]
4501os.uname
4502
4503Return an object identifying the current operating system.
4504
4505The object behaves like a named tuple with the following fields:
4506 (sysname, nodename, release, version, machine)
4507
4508[clinic start generated code]*/
4509
Larry Hastings2f936352014-08-05 14:04:04 +10004510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004511os_uname_impl(PyObject *module)
4512/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004513{
Victor Stinner8c62be82010-05-06 00:08:46 +00004514 struct utsname u;
4515 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004516 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004517
Victor Stinner8c62be82010-05-06 00:08:46 +00004518 Py_BEGIN_ALLOW_THREADS
4519 res = uname(&u);
4520 Py_END_ALLOW_THREADS
4521 if (res < 0)
4522 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004523
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004524 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004525 if (value == NULL)
4526 return NULL;
4527
4528#define SET(i, field) \
4529 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004530 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004531 if (!o) { \
4532 Py_DECREF(value); \
4533 return NULL; \
4534 } \
4535 PyStructSequence_SET_ITEM(value, i, o); \
4536 } \
4537
4538 SET(0, u.sysname);
4539 SET(1, u.nodename);
4540 SET(2, u.release);
4541 SET(3, u.version);
4542 SET(4, u.machine);
4543
4544#undef SET
4545
4546 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004547}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004548#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004549
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004550
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551
4552typedef struct {
4553 int now;
4554 time_t atime_s;
4555 long atime_ns;
4556 time_t mtime_s;
4557 long mtime_ns;
4558} utime_t;
4559
4560/*
Victor Stinner484df002014-10-09 13:52:31 +02004561 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562 * they also intentionally leak the declaration of a pointer named "time"
4563 */
4564#define UTIME_TO_TIMESPEC \
4565 struct timespec ts[2]; \
4566 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004567 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004568 time = NULL; \
4569 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004570 ts[0].tv_sec = ut->atime_s; \
4571 ts[0].tv_nsec = ut->atime_ns; \
4572 ts[1].tv_sec = ut->mtime_s; \
4573 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 time = ts; \
4575 } \
4576
4577#define UTIME_TO_TIMEVAL \
4578 struct timeval tv[2]; \
4579 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004580 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581 time = NULL; \
4582 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004583 tv[0].tv_sec = ut->atime_s; \
4584 tv[0].tv_usec = ut->atime_ns / 1000; \
4585 tv[1].tv_sec = ut->mtime_s; \
4586 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587 time = tv; \
4588 } \
4589
4590#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004591 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004593 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 time = NULL; \
4595 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004596 u.actime = ut->atime_s; \
4597 u.modtime = ut->mtime_s; \
4598 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004599 }
4600
4601#define UTIME_TO_TIME_T \
4602 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004603 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004604 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605 time = NULL; \
4606 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004607 timet[0] = ut->atime_s; \
4608 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004609 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610 } \
4611
4612
Victor Stinner528a9ab2015-09-03 21:30:26 +02004613#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004614
4615static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004616utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004617{
4618#ifdef HAVE_UTIMENSAT
4619 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4620 UTIME_TO_TIMESPEC;
4621 return utimensat(dir_fd, path, time, flags);
4622#elif defined(HAVE_FUTIMESAT)
4623 UTIME_TO_TIMEVAL;
4624 /*
4625 * follow_symlinks will never be false here;
4626 * we only allow !follow_symlinks and dir_fd together
4627 * if we have utimensat()
4628 */
4629 assert(follow_symlinks);
4630 return futimesat(dir_fd, path, time);
4631#endif
4632}
4633
Larry Hastings2f936352014-08-05 14:04:04 +10004634 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4635#else
4636 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637#endif
4638
Victor Stinner528a9ab2015-09-03 21:30:26 +02004639#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640
4641static int
Victor Stinner484df002014-10-09 13:52:31 +02004642utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004643{
4644#ifdef HAVE_FUTIMENS
4645 UTIME_TO_TIMESPEC;
4646 return futimens(fd, time);
4647#else
4648 UTIME_TO_TIMEVAL;
4649 return futimes(fd, time);
4650#endif
4651}
4652
Larry Hastings2f936352014-08-05 14:04:04 +10004653 #define PATH_UTIME_HAVE_FD 1
4654#else
4655 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004656#endif
4657
Victor Stinner5ebae872015-09-22 01:29:33 +02004658#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4659# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4660#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004661
Victor Stinner4552ced2015-09-21 22:37:15 +02004662#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663
4664static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004665utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004666{
4667#ifdef HAVE_UTIMENSAT
4668 UTIME_TO_TIMESPEC;
4669 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4670#else
4671 UTIME_TO_TIMEVAL;
4672 return lutimes(path, time);
4673#endif
4674}
4675
4676#endif
4677
4678#ifndef MS_WINDOWS
4679
4680static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004681utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682{
4683#ifdef HAVE_UTIMENSAT
4684 UTIME_TO_TIMESPEC;
4685 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4686#elif defined(HAVE_UTIMES)
4687 UTIME_TO_TIMEVAL;
4688 return utimes(path, time);
4689#elif defined(HAVE_UTIME_H)
4690 UTIME_TO_UTIMBUF;
4691 return utime(path, time);
4692#else
4693 UTIME_TO_TIME_T;
4694 return utime(path, time);
4695#endif
4696}
4697
4698#endif
4699
Larry Hastings76ad59b2012-05-03 00:30:07 -07004700static int
4701split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4702{
4703 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004704 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004705 divmod = PyNumber_Divmod(py_long, billion);
4706 if (!divmod)
4707 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004708 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4709 PyErr_Format(PyExc_TypeError,
4710 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4711 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4712 goto exit;
4713 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004714 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4715 if ((*s == -1) && PyErr_Occurred())
4716 goto exit;
4717 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004718 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004719 goto exit;
4720
4721 result = 1;
4722exit:
4723 Py_XDECREF(divmod);
4724 return result;
4725}
4726
Larry Hastings2f936352014-08-05 14:04:04 +10004727
4728/*[clinic input]
4729os.utime
4730
4731 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4732 times: object = NULL
4733 *
4734 ns: object = NULL
4735 dir_fd: dir_fd(requires='futimensat') = None
4736 follow_symlinks: bool=True
4737
Martin Panter0ff89092015-09-09 01:56:53 +00004738# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004739
4740Set the access and modified time of path.
4741
4742path may always be specified as a string.
4743On some platforms, path may also be specified as an open file descriptor.
4744 If this functionality is unavailable, using it raises an exception.
4745
4746If times is not None, it must be a tuple (atime, mtime);
4747 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004748If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004749 atime_ns and mtime_ns should be expressed as integer nanoseconds
4750 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004751If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004752Specifying tuples for both times and ns is an error.
4753
4754If dir_fd is not None, it should be a file descriptor open to a directory,
4755 and path should be relative; path will then be relative to that directory.
4756If follow_symlinks is False, and the last element of the path is a symbolic
4757 link, utime will modify the symbolic link itself instead of the file the
4758 link points to.
4759It is an error to use dir_fd or follow_symlinks when specifying path
4760 as an open file descriptor.
4761dir_fd and follow_symlinks may not be available on your platform.
4762 If they are unavailable, using them will raise a NotImplementedError.
4763
4764[clinic start generated code]*/
4765
Larry Hastings2f936352014-08-05 14:04:04 +10004766static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004767os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4768 int dir_fd, int follow_symlinks)
4769/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004770{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771#ifdef MS_WINDOWS
4772 HANDLE hFile;
4773 FILETIME atime, mtime;
4774#else
4775 int result;
4776#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777
Larry Hastings2f936352014-08-05 14:04:04 +10004778 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004779
Christian Heimesb3c87242013-08-01 00:08:16 +02004780 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004781
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 if (times && (times != Py_None) && ns) {
4783 PyErr_SetString(PyExc_ValueError,
4784 "utime: you may specify either 'times'"
4785 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004786 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004787 }
4788
4789 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004790 time_t a_sec, m_sec;
4791 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004792 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793 PyErr_SetString(PyExc_TypeError,
4794 "utime: 'times' must be either"
4795 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004796 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004797 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004799 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004800 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004801 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004802 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004803 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004804 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004805 utime.atime_s = a_sec;
4806 utime.atime_ns = a_nsec;
4807 utime.mtime_s = m_sec;
4808 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004809 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004811 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812 PyErr_SetString(PyExc_TypeError,
4813 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004814 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004815 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004817 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004819 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004820 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004821 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004822 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004823 }
4824 else {
4825 /* times and ns are both None/unspecified. use "now". */
4826 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004827 }
4828
Victor Stinner4552ced2015-09-21 22:37:15 +02004829#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004831 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004833
Larry Hastings2f936352014-08-05 14:04:04 +10004834 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4835 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4836 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004837 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004838
Larry Hastings9cf065c2012-06-22 16:30:09 -07004839#if !defined(HAVE_UTIMENSAT)
4840 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004841 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 "utime: cannot use dir_fd and follow_symlinks "
4843 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004844 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845 }
4846#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004847
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004848#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004849 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004850 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4851 NULL, OPEN_EXISTING,
4852 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004853 Py_END_ALLOW_THREADS
4854 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004855 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004856 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004857 }
4858
Larry Hastings9cf065c2012-06-22 16:30:09 -07004859 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004860 GetSystemTimeAsFileTime(&mtime);
4861 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004864 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4865 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 }
4867 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4868 /* Avoid putting the file name into the error here,
4869 as that may confuse the user into believing that
4870 something is wrong with the file, when it also
4871 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004872 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004873 CloseHandle(hFile);
4874 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004876 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004877#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004878 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004879
Victor Stinner4552ced2015-09-21 22:37:15 +02004880#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004881 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004882 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004884#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004885
Victor Stinner528a9ab2015-09-03 21:30:26 +02004886#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004887 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004888 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 else
4890#endif
4891
Victor Stinner528a9ab2015-09-03 21:30:26 +02004892#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004893 if (path->fd != -1)
4894 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004895 else
4896#endif
4897
Larry Hastings2f936352014-08-05 14:04:04 +10004898 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004899
4900 Py_END_ALLOW_THREADS
4901
4902 if (result < 0) {
4903 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004904 posix_error();
4905 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004906 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004907
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004908#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004910 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004911}
4912
Guido van Rossum3b066191991-06-04 19:40:25 +00004913/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004914
Larry Hastings2f936352014-08-05 14:04:04 +10004915
4916/*[clinic input]
4917os._exit
4918
4919 status: int
4920
4921Exit to the system with specified status, without normal exit processing.
4922[clinic start generated code]*/
4923
Larry Hastings2f936352014-08-05 14:04:04 +10004924static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004925os__exit_impl(PyObject *module, int status)
4926/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004927{
4928 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004930}
4931
Steve Dowercc16be82016-09-08 10:35:16 -07004932#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4933#define EXECV_CHAR wchar_t
4934#else
4935#define EXECV_CHAR char
4936#endif
4937
pxinwrf2d7ac72019-05-21 18:46:37 +08004938#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004939static void
Steve Dowercc16be82016-09-08 10:35:16 -07004940free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004941{
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 Py_ssize_t i;
4943 for (i = 0; i < count; i++)
4944 PyMem_Free(array[i]);
4945 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004946}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004947
Berker Peksag81816462016-09-15 20:19:47 +03004948static int
4949fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004950{
Victor Stinner8c62be82010-05-06 00:08:46 +00004951 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004952 PyObject *ub;
4953 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004954#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004955 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004956 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004957 *out = PyUnicode_AsWideCharString(ub, &size);
4958 if (*out)
4959 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004960#else
Berker Peksag81816462016-09-15 20:19:47 +03004961 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004963 size = PyBytes_GET_SIZE(ub);
4964 *out = PyMem_Malloc(size + 1);
4965 if (*out) {
4966 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4967 result = 1;
4968 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004969 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004970#endif
Berker Peksag81816462016-09-15 20:19:47 +03004971 Py_DECREF(ub);
4972 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004973}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004974#endif
4975
pxinwrf2d7ac72019-05-21 18:46:37 +08004976#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07004977static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004978parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4979{
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 Py_ssize_t i, pos, envc;
4981 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004982 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004983 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 i = PyMapping_Size(env);
4986 if (i < 0)
4987 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004988 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 if (envlist == NULL) {
4990 PyErr_NoMemory();
4991 return NULL;
4992 }
4993 envc = 0;
4994 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004995 if (!keys)
4996 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004998 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 goto error;
5000 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5001 PyErr_Format(PyExc_TypeError,
5002 "env.keys() or env.values() is not a list");
5003 goto error;
5004 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005005
Victor Stinner8c62be82010-05-06 00:08:46 +00005006 for (pos = 0; pos < i; pos++) {
5007 key = PyList_GetItem(keys, pos);
5008 val = PyList_GetItem(vals, pos);
5009 if (!key || !val)
5010 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005011
Berker Peksag81816462016-09-15 20:19:47 +03005012#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5013 if (!PyUnicode_FSDecoder(key, &key2))
5014 goto error;
5015 if (!PyUnicode_FSDecoder(val, &val2)) {
5016 Py_DECREF(key2);
5017 goto error;
5018 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005019 /* Search from index 1 because on Windows starting '=' is allowed for
5020 defining hidden environment variables. */
5021 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5022 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5023 {
5024 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005025 Py_DECREF(key2);
5026 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005027 goto error;
5028 }
Berker Peksag81816462016-09-15 20:19:47 +03005029 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5030#else
5031 if (!PyUnicode_FSConverter(key, &key2))
5032 goto error;
5033 if (!PyUnicode_FSConverter(val, &val2)) {
5034 Py_DECREF(key2);
5035 goto error;
5036 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005037 if (PyBytes_GET_SIZE(key2) == 0 ||
5038 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5039 {
5040 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005041 Py_DECREF(key2);
5042 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005043 goto error;
5044 }
Berker Peksag81816462016-09-15 20:19:47 +03005045 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5046 PyBytes_AS_STRING(val2));
5047#endif
5048 Py_DECREF(key2);
5049 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005050 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005052
5053 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5054 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 goto error;
5056 }
Berker Peksag81816462016-09-15 20:19:47 +03005057
Steve Dowercc16be82016-09-08 10:35:16 -07005058 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 }
5060 Py_DECREF(vals);
5061 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 envlist[envc] = 0;
5064 *envc_ptr = envc;
5065 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005066
5067error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 Py_XDECREF(keys);
5069 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005070 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005072}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005073
Steve Dowercc16be82016-09-08 10:35:16 -07005074static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005075parse_arglist(PyObject* argv, Py_ssize_t *argc)
5076{
5077 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005078 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005079 if (argvlist == NULL) {
5080 PyErr_NoMemory();
5081 return NULL;
5082 }
5083 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005084 PyObject* item = PySequence_ITEM(argv, i);
5085 if (item == NULL)
5086 goto fail;
5087 if (!fsconvert_strdup(item, &argvlist[i])) {
5088 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005089 goto fail;
5090 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005091 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005092 }
5093 argvlist[*argc] = NULL;
5094 return argvlist;
5095fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005096 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097 free_string_array(argvlist, *argc);
5098 return NULL;
5099}
Steve Dowercc16be82016-09-08 10:35:16 -07005100
Ross Lagerwall7807c352011-03-17 20:20:30 +02005101#endif
5102
Larry Hastings2f936352014-08-05 14:04:04 +10005103
Ross Lagerwall7807c352011-03-17 20:20:30 +02005104#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005105/*[clinic input]
5106os.execv
5107
Steve Dowercc16be82016-09-08 10:35:16 -07005108 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005109 Path of executable file.
5110 argv: object
5111 Tuple or list of strings.
5112 /
5113
5114Execute an executable path with arguments, replacing current process.
5115[clinic start generated code]*/
5116
Larry Hastings2f936352014-08-05 14:04:04 +10005117static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005118os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5119/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005120{
Steve Dowercc16be82016-09-08 10:35:16 -07005121 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005122 Py_ssize_t argc;
5123
5124 /* execv has two arguments: (path, argv), where
5125 argv is a list or tuple of strings. */
5126
Ross Lagerwall7807c352011-03-17 20:20:30 +02005127 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5128 PyErr_SetString(PyExc_TypeError,
5129 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005130 return NULL;
5131 }
5132 argc = PySequence_Size(argv);
5133 if (argc < 1) {
5134 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005135 return NULL;
5136 }
5137
5138 argvlist = parse_arglist(argv, &argc);
5139 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005140 return NULL;
5141 }
Steve Dowerbce26262016-11-19 19:17:26 -08005142 if (!argvlist[0][0]) {
5143 PyErr_SetString(PyExc_ValueError,
5144 "execv() arg 2 first element cannot be empty");
5145 free_string_array(argvlist, argc);
5146 return NULL;
5147 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005148
Steve Dowerbce26262016-11-19 19:17:26 -08005149 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005150#ifdef HAVE_WEXECV
5151 _wexecv(path->wide, argvlist);
5152#else
5153 execv(path->narrow, argvlist);
5154#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005155 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005156
5157 /* If we get here it's definitely an error */
5158
5159 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005160 return posix_error();
5161}
5162
Larry Hastings2f936352014-08-05 14:04:04 +10005163
5164/*[clinic input]
5165os.execve
5166
5167 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5168 Path of executable file.
5169 argv: object
5170 Tuple or list of strings.
5171 env: object
5172 Dictionary of strings mapping to strings.
5173
5174Execute an executable path with arguments, replacing current process.
5175[clinic start generated code]*/
5176
Larry Hastings2f936352014-08-05 14:04:04 +10005177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005178os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5179/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005180{
Steve Dowercc16be82016-09-08 10:35:16 -07005181 EXECV_CHAR **argvlist = NULL;
5182 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005183 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005184
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 /* execve has three arguments: (path, argv, env), where
5186 argv is a list or tuple of strings and env is a dictionary
5187 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005188
Ross Lagerwall7807c352011-03-17 20:20:30 +02005189 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005191 "execve: argv must be a tuple or list");
5192 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005194 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005195 if (argc < 1) {
5196 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5197 return NULL;
5198 }
5199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 if (!PyMapping_Check(env)) {
5201 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005202 "execve: environment must be a mapping object");
5203 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005205
Ross Lagerwall7807c352011-03-17 20:20:30 +02005206 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005208 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 }
Steve Dowerbce26262016-11-19 19:17:26 -08005210 if (!argvlist[0][0]) {
5211 PyErr_SetString(PyExc_ValueError,
5212 "execve: argv first element cannot be empty");
5213 goto fail;
5214 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005215
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 envlist = parse_envlist(env, &envc);
5217 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005218 goto fail;
5219
Steve Dowerbce26262016-11-19 19:17:26 -08005220 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005221#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005222 if (path->fd > -1)
5223 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005224 else
5225#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005226#ifdef HAVE_WEXECV
5227 _wexecve(path->wide, argvlist, envlist);
5228#else
Larry Hastings2f936352014-08-05 14:04:04 +10005229 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005230#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005231 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005232
5233 /* If we get here it's definitely an error */
5234
Alexey Izbyshev83460312018-10-20 03:28:22 +03005235 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005236
Steve Dowercc16be82016-09-08 10:35:16 -07005237 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005238 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005239 if (argvlist)
5240 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005241 return NULL;
5242}
Steve Dowercc16be82016-09-08 10:35:16 -07005243
Larry Hastings9cf065c2012-06-22 16:30:09 -07005244#endif /* HAVE_EXECV */
5245
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005246#ifdef HAVE_POSIX_SPAWN
5247
5248enum posix_spawn_file_actions_identifier {
5249 POSIX_SPAWN_OPEN,
5250 POSIX_SPAWN_CLOSE,
5251 POSIX_SPAWN_DUP2
5252};
5253
William Orr81574b82018-10-01 22:19:56 -07005254#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005255static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005256convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005257#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005258
5259static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005260parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5261 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005262 PyObject *setsigdef, PyObject *scheduler,
5263 posix_spawnattr_t *attrp)
5264{
5265 long all_flags = 0;
5266
5267 errno = posix_spawnattr_init(attrp);
5268 if (errno) {
5269 posix_error();
5270 return -1;
5271 }
5272
5273 if (setpgroup) {
5274 pid_t pgid = PyLong_AsPid(setpgroup);
5275 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5276 goto fail;
5277 }
5278 errno = posix_spawnattr_setpgroup(attrp, pgid);
5279 if (errno) {
5280 posix_error();
5281 goto fail;
5282 }
5283 all_flags |= POSIX_SPAWN_SETPGROUP;
5284 }
5285
5286 if (resetids) {
5287 all_flags |= POSIX_SPAWN_RESETIDS;
5288 }
5289
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005290 if (setsid) {
5291#ifdef POSIX_SPAWN_SETSID
5292 all_flags |= POSIX_SPAWN_SETSID;
5293#elif defined(POSIX_SPAWN_SETSID_NP)
5294 all_flags |= POSIX_SPAWN_SETSID_NP;
5295#else
5296 argument_unavailable_error(func_name, "setsid");
5297 return -1;
5298#endif
5299 }
5300
Pablo Galindo254a4662018-09-07 16:44:24 +01005301 if (setsigmask) {
5302 sigset_t set;
5303 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5304 goto fail;
5305 }
5306 errno = posix_spawnattr_setsigmask(attrp, &set);
5307 if (errno) {
5308 posix_error();
5309 goto fail;
5310 }
5311 all_flags |= POSIX_SPAWN_SETSIGMASK;
5312 }
5313
5314 if (setsigdef) {
5315 sigset_t set;
5316 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5317 goto fail;
5318 }
5319 errno = posix_spawnattr_setsigdefault(attrp, &set);
5320 if (errno) {
5321 posix_error();
5322 goto fail;
5323 }
5324 all_flags |= POSIX_SPAWN_SETSIGDEF;
5325 }
5326
5327 if (scheduler) {
5328#ifdef POSIX_SPAWN_SETSCHEDULER
5329 PyObject *py_schedpolicy;
5330 struct sched_param schedparam;
5331
5332 if (!PyArg_ParseTuple(scheduler, "OO&"
5333 ";A scheduler tuple must have two elements",
5334 &py_schedpolicy, convert_sched_param, &schedparam)) {
5335 goto fail;
5336 }
5337 if (py_schedpolicy != Py_None) {
5338 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5339
5340 if (schedpolicy == -1 && PyErr_Occurred()) {
5341 goto fail;
5342 }
5343 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5344 if (errno) {
5345 posix_error();
5346 goto fail;
5347 }
5348 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5349 }
5350 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5351 if (errno) {
5352 posix_error();
5353 goto fail;
5354 }
5355 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5356#else
5357 PyErr_SetString(PyExc_NotImplementedError,
5358 "The scheduler option is not supported in this system.");
5359 goto fail;
5360#endif
5361 }
5362
5363 errno = posix_spawnattr_setflags(attrp, all_flags);
5364 if (errno) {
5365 posix_error();
5366 goto fail;
5367 }
5368
5369 return 0;
5370
5371fail:
5372 (void)posix_spawnattr_destroy(attrp);
5373 return -1;
5374}
5375
5376static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005377parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005378 posix_spawn_file_actions_t *file_actionsp,
5379 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005380{
5381 PyObject *seq;
5382 PyObject *file_action = NULL;
5383 PyObject *tag_obj;
5384
5385 seq = PySequence_Fast(file_actions,
5386 "file_actions must be a sequence or None");
5387 if (seq == NULL) {
5388 return -1;
5389 }
5390
5391 errno = posix_spawn_file_actions_init(file_actionsp);
5392 if (errno) {
5393 posix_error();
5394 Py_DECREF(seq);
5395 return -1;
5396 }
5397
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005398 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005399 file_action = PySequence_Fast_GET_ITEM(seq, i);
5400 Py_INCREF(file_action);
5401 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5402 PyErr_SetString(PyExc_TypeError,
5403 "Each file_actions element must be a non-empty tuple");
5404 goto fail;
5405 }
5406 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5407 if (tag == -1 && PyErr_Occurred()) {
5408 goto fail;
5409 }
5410
5411 /* Populate the file_actions object */
5412 switch (tag) {
5413 case POSIX_SPAWN_OPEN: {
5414 int fd, oflag;
5415 PyObject *path;
5416 unsigned long mode;
5417 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5418 ";A open file_action tuple must have 5 elements",
5419 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5420 &oflag, &mode))
5421 {
5422 goto fail;
5423 }
Pablo Galindocb970732018-06-19 09:19:50 +01005424 if (PyList_Append(temp_buffer, path)) {
5425 Py_DECREF(path);
5426 goto fail;
5427 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005428 errno = posix_spawn_file_actions_addopen(file_actionsp,
5429 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005430 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005431 if (errno) {
5432 posix_error();
5433 goto fail;
5434 }
5435 break;
5436 }
5437 case POSIX_SPAWN_CLOSE: {
5438 int fd;
5439 if (!PyArg_ParseTuple(file_action, "Oi"
5440 ";A close file_action tuple must have 2 elements",
5441 &tag_obj, &fd))
5442 {
5443 goto fail;
5444 }
5445 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5446 if (errno) {
5447 posix_error();
5448 goto fail;
5449 }
5450 break;
5451 }
5452 case POSIX_SPAWN_DUP2: {
5453 int fd1, fd2;
5454 if (!PyArg_ParseTuple(file_action, "Oii"
5455 ";A dup2 file_action tuple must have 3 elements",
5456 &tag_obj, &fd1, &fd2))
5457 {
5458 goto fail;
5459 }
5460 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5461 fd1, fd2);
5462 if (errno) {
5463 posix_error();
5464 goto fail;
5465 }
5466 break;
5467 }
5468 default: {
5469 PyErr_SetString(PyExc_TypeError,
5470 "Unknown file_actions identifier");
5471 goto fail;
5472 }
5473 }
5474 Py_DECREF(file_action);
5475 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005476
Serhiy Storchakaef347532018-05-01 16:45:04 +03005477 Py_DECREF(seq);
5478 return 0;
5479
5480fail:
5481 Py_DECREF(seq);
5482 Py_DECREF(file_action);
5483 (void)posix_spawn_file_actions_destroy(file_actionsp);
5484 return -1;
5485}
5486
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005487
5488static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005489py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5490 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005491 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005492 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005493{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005494 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005495 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005496 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005497 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005498 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005499 posix_spawnattr_t attr;
5500 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005501 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005502 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005503 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005504 pid_t pid;
5505 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005506
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005507 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005508 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005509 like posix.environ. */
5510
Serhiy Storchakaef347532018-05-01 16:45:04 +03005511 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005512 PyErr_Format(PyExc_TypeError,
5513 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005514 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005515 }
5516 argc = PySequence_Size(argv);
5517 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005518 PyErr_Format(PyExc_ValueError,
5519 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005520 return NULL;
5521 }
5522
5523 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005524 PyErr_Format(PyExc_TypeError,
5525 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005526 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005527 }
5528
5529 argvlist = parse_arglist(argv, &argc);
5530 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005531 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005532 }
5533 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005534 PyErr_Format(PyExc_ValueError,
5535 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005536 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005537 }
5538
5539 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005540 if (envlist == NULL) {
5541 goto exit;
5542 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005543
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005544 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005545 /* There is a bug in old versions of glibc that makes some of the
5546 * helper functions for manipulating file actions not copy the provided
5547 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5548 * copy the value of path for some old versions of glibc (<2.20).
5549 * The use of temp_buffer here is a workaround that keeps the
5550 * python objects that own the buffers alive until posix_spawn gets called.
5551 * Check https://bugs.python.org/issue33630 and
5552 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5553 temp_buffer = PyList_New(0);
5554 if (!temp_buffer) {
5555 goto exit;
5556 }
5557 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005558 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005559 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005560 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005561 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005562
Victor Stinner325e4ba2019-02-01 15:47:24 +01005563 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5564 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005565 goto exit;
5566 }
5567 attrp = &attr;
5568
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005569 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005570#ifdef HAVE_POSIX_SPAWNP
5571 if (use_posix_spawnp) {
5572 err_code = posix_spawnp(&pid, path->narrow,
5573 file_actionsp, attrp, argvlist, envlist);
5574 }
5575 else
5576#endif /* HAVE_POSIX_SPAWNP */
5577 {
5578 err_code = posix_spawn(&pid, path->narrow,
5579 file_actionsp, attrp, argvlist, envlist);
5580 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005581 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005582
Serhiy Storchakaef347532018-05-01 16:45:04 +03005583 if (err_code) {
5584 errno = err_code;
5585 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005586 goto exit;
5587 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005588#ifdef _Py_MEMORY_SANITIZER
5589 __msan_unpoison(&pid, sizeof(pid));
5590#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005591 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005592
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005593exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005594 if (file_actionsp) {
5595 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005596 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005597 if (attrp) {
5598 (void)posix_spawnattr_destroy(attrp);
5599 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005600 if (envlist) {
5601 free_string_array(envlist, envc);
5602 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005603 if (argvlist) {
5604 free_string_array(argvlist, argc);
5605 }
Pablo Galindocb970732018-06-19 09:19:50 +01005606 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005607 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005608}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005609
5610
5611/*[clinic input]
5612
5613os.posix_spawn
5614 path: path_t
5615 Path of executable file.
5616 argv: object
5617 Tuple or list of strings.
5618 env: object
5619 Dictionary of strings mapping to strings.
5620 /
5621 *
5622 file_actions: object(c_default='NULL') = ()
5623 A sequence of file action tuples.
5624 setpgroup: object = NULL
5625 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5626 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005627 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5628 setsid: bool(accept={int}) = False
5629 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005630 setsigmask: object(c_default='NULL') = ()
5631 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5632 setsigdef: object(c_default='NULL') = ()
5633 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5634 scheduler: object = NULL
5635 A tuple with the scheduler policy (optional) and parameters.
5636
5637Execute the program specified by path in a new process.
5638[clinic start generated code]*/
5639
5640static PyObject *
5641os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5642 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005643 PyObject *setpgroup, int resetids, int setsid,
5644 PyObject *setsigmask, PyObject *setsigdef,
5645 PyObject *scheduler)
5646/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005647{
5648 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005649 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005650 scheduler);
5651}
5652 #endif /* HAVE_POSIX_SPAWN */
5653
5654
5655
5656#ifdef HAVE_POSIX_SPAWNP
5657/*[clinic input]
5658
5659os.posix_spawnp
5660 path: path_t
5661 Path of executable file.
5662 argv: object
5663 Tuple or list of strings.
5664 env: object
5665 Dictionary of strings mapping to strings.
5666 /
5667 *
5668 file_actions: object(c_default='NULL') = ()
5669 A sequence of file action tuples.
5670 setpgroup: object = NULL
5671 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5672 resetids: bool(accept={int}) = False
5673 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005674 setsid: bool(accept={int}) = False
5675 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005676 setsigmask: object(c_default='NULL') = ()
5677 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5678 setsigdef: object(c_default='NULL') = ()
5679 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5680 scheduler: object = NULL
5681 A tuple with the scheduler policy (optional) and parameters.
5682
5683Execute the program specified by path in a new process.
5684[clinic start generated code]*/
5685
5686static PyObject *
5687os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5688 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005689 PyObject *setpgroup, int resetids, int setsid,
5690 PyObject *setsigmask, PyObject *setsigdef,
5691 PyObject *scheduler)
5692/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005693{
5694 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005695 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005696 scheduler);
5697}
5698#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005699
pxinwrf2d7ac72019-05-21 18:46:37 +08005700#ifdef HAVE_RTPSPAWN
5701static intptr_t
5702_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5703 const char *envp[])
5704{
5705 RTP_ID rtpid;
5706 int status;
5707 pid_t res;
5708 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005709
pxinwrf2d7ac72019-05-21 18:46:37 +08005710 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5711 uStackSize=0 cannot be used, the default stack size is too small for
5712 Python. */
5713 if (envp) {
5714 rtpid = rtpSpawn(rtpFileName, argv, envp,
5715 100, 0x1000000, 0, VX_FP_TASK);
5716 }
5717 else {
5718 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5719 100, 0x1000000, 0, VX_FP_TASK);
5720 }
5721 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5722 do {
5723 res = waitpid((pid_t)rtpid, &status, 0);
5724 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5725
5726 if (res < 0)
5727 return RTP_ID_ERROR;
5728 return ((intptr_t)status);
5729 }
5730 return ((intptr_t)rtpid);
5731}
5732#endif
5733
5734#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005735/*[clinic input]
5736os.spawnv
5737
5738 mode: int
5739 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005740 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005741 Path of executable file.
5742 argv: object
5743 Tuple or list of strings.
5744 /
5745
5746Execute the program specified by path in a new process.
5747[clinic start generated code]*/
5748
Larry Hastings2f936352014-08-05 14:04:04 +10005749static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005750os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5751/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005752{
Steve Dowercc16be82016-09-08 10:35:16 -07005753 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005754 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005755 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005756 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005757 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005758
Victor Stinner8c62be82010-05-06 00:08:46 +00005759 /* spawnv has three arguments: (mode, path, argv), where
5760 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005761
Victor Stinner8c62be82010-05-06 00:08:46 +00005762 if (PyList_Check(argv)) {
5763 argc = PyList_Size(argv);
5764 getitem = PyList_GetItem;
5765 }
5766 else if (PyTuple_Check(argv)) {
5767 argc = PyTuple_Size(argv);
5768 getitem = PyTuple_GetItem;
5769 }
5770 else {
5771 PyErr_SetString(PyExc_TypeError,
5772 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005773 return NULL;
5774 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005775 if (argc == 0) {
5776 PyErr_SetString(PyExc_ValueError,
5777 "spawnv() arg 2 cannot be empty");
5778 return NULL;
5779 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005780
Steve Dowercc16be82016-09-08 10:35:16 -07005781 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005782 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005783 return PyErr_NoMemory();
5784 }
5785 for (i = 0; i < argc; i++) {
5786 if (!fsconvert_strdup((*getitem)(argv, i),
5787 &argvlist[i])) {
5788 free_string_array(argvlist, i);
5789 PyErr_SetString(
5790 PyExc_TypeError,
5791 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 return NULL;
5793 }
Steve Dower93ff8722016-11-19 19:03:54 -08005794 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005795 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005796 PyErr_SetString(
5797 PyExc_ValueError,
5798 "spawnv() arg 2 first element cannot be empty");
5799 return NULL;
5800 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 }
5802 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005803
pxinwrf2d7ac72019-05-21 18:46:37 +08005804#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 if (mode == _OLD_P_OVERLAY)
5806 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005807#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005808
Victor Stinner8c62be82010-05-06 00:08:46 +00005809 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005810 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005811#ifdef HAVE_WSPAWNV
5812 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005813#elif defined(HAVE_RTPSPAWN)
5814 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005815#else
5816 spawnval = _spawnv(mode, path->narrow, argvlist);
5817#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005818 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005819 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005820
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005822
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 if (spawnval == -1)
5824 return posix_error();
5825 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005826 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005827}
5828
Larry Hastings2f936352014-08-05 14:04:04 +10005829/*[clinic input]
5830os.spawnve
5831
5832 mode: int
5833 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005834 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005835 Path of executable file.
5836 argv: object
5837 Tuple or list of strings.
5838 env: object
5839 Dictionary of strings mapping to strings.
5840 /
5841
5842Execute the program specified by path in a new process.
5843[clinic start generated code]*/
5844
Larry Hastings2f936352014-08-05 14:04:04 +10005845static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005846os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005847 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005848/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005849{
Steve Dowercc16be82016-09-08 10:35:16 -07005850 EXECV_CHAR **argvlist;
5851 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005852 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005853 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005854 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005855 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005856 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005857
Victor Stinner8c62be82010-05-06 00:08:46 +00005858 /* spawnve has four arguments: (mode, path, argv, env), where
5859 argv is a list or tuple of strings and env is a dictionary
5860 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005861
Victor Stinner8c62be82010-05-06 00:08:46 +00005862 if (PyList_Check(argv)) {
5863 argc = PyList_Size(argv);
5864 getitem = PyList_GetItem;
5865 }
5866 else if (PyTuple_Check(argv)) {
5867 argc = PyTuple_Size(argv);
5868 getitem = PyTuple_GetItem;
5869 }
5870 else {
5871 PyErr_SetString(PyExc_TypeError,
5872 "spawnve() arg 2 must be a tuple or list");
5873 goto fail_0;
5874 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005875 if (argc == 0) {
5876 PyErr_SetString(PyExc_ValueError,
5877 "spawnve() arg 2 cannot be empty");
5878 goto fail_0;
5879 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005880 if (!PyMapping_Check(env)) {
5881 PyErr_SetString(PyExc_TypeError,
5882 "spawnve() arg 3 must be a mapping object");
5883 goto fail_0;
5884 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005885
Steve Dowercc16be82016-09-08 10:35:16 -07005886 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005887 if (argvlist == NULL) {
5888 PyErr_NoMemory();
5889 goto fail_0;
5890 }
5891 for (i = 0; i < argc; i++) {
5892 if (!fsconvert_strdup((*getitem)(argv, i),
5893 &argvlist[i]))
5894 {
5895 lastarg = i;
5896 goto fail_1;
5897 }
Steve Dowerbce26262016-11-19 19:17:26 -08005898 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005899 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005900 PyErr_SetString(
5901 PyExc_ValueError,
5902 "spawnv() arg 2 first element cannot be empty");
5903 goto fail_1;
5904 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 }
5906 lastarg = argc;
5907 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005908
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 envlist = parse_envlist(env, &envc);
5910 if (envlist == NULL)
5911 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005912
pxinwrf2d7ac72019-05-21 18:46:37 +08005913#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 if (mode == _OLD_P_OVERLAY)
5915 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005916#endif
Tim Peters25059d32001-12-07 20:35:43 +00005917
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005919 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005920#ifdef HAVE_WSPAWNV
5921 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005922#elif defined(HAVE_RTPSPAWN)
5923 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
5924 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005925#else
5926 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5927#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005928 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005930
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 if (spawnval == -1)
5932 (void) posix_error();
5933 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005934 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005935
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 while (--envc >= 0)
5937 PyMem_DEL(envlist[envc]);
5938 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005939 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005940 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005941 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005943}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005944
Guido van Rossuma1065681999-01-25 23:20:23 +00005945#endif /* HAVE_SPAWNV */
5946
5947
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005948#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005949
5950/* Helper function to validate arguments.
5951 Returns 0 on success. non-zero on failure with a TypeError raised.
5952 If obj is non-NULL it must be callable. */
5953static int
5954check_null_or_callable(PyObject *obj, const char* obj_name)
5955{
5956 if (obj && !PyCallable_Check(obj)) {
5957 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5958 obj_name, Py_TYPE(obj)->tp_name);
5959 return -1;
5960 }
5961 return 0;
5962}
5963
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005964/*[clinic input]
5965os.register_at_fork
5966
Gregory P. Smith163468a2017-05-29 10:03:41 -07005967 *
5968 before: object=NULL
5969 A callable to be called in the parent before the fork() syscall.
5970 after_in_child: object=NULL
5971 A callable to be called in the child after fork().
5972 after_in_parent: object=NULL
5973 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005974
Gregory P. Smith163468a2017-05-29 10:03:41 -07005975Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005976
Gregory P. Smith163468a2017-05-29 10:03:41 -07005977'before' callbacks are called in reverse order.
5978'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005979
5980[clinic start generated code]*/
5981
5982static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005983os_register_at_fork_impl(PyObject *module, PyObject *before,
5984 PyObject *after_in_child, PyObject *after_in_parent)
5985/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005986{
5987 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005988
Gregory P. Smith163468a2017-05-29 10:03:41 -07005989 if (!before && !after_in_child && !after_in_parent) {
5990 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5991 return NULL;
5992 }
5993 if (check_null_or_callable(before, "before") ||
5994 check_null_or_callable(after_in_child, "after_in_child") ||
5995 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005996 return NULL;
5997 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005998 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005999
Gregory P. Smith163468a2017-05-29 10:03:41 -07006000 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006001 return NULL;
6002 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006003 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006004 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006005 }
6006 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6007 return NULL;
6008 }
6009 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006010}
6011#endif /* HAVE_FORK */
6012
6013
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006014#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006015/*[clinic input]
6016os.fork1
6017
6018Fork a child process with a single multiplexed (i.e., not bound) thread.
6019
6020Return 0 to child process and PID of child to parent process.
6021[clinic start generated code]*/
6022
Larry Hastings2f936352014-08-05 14:04:04 +10006023static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006024os_fork1_impl(PyObject *module)
6025/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006026{
Victor Stinner8c62be82010-05-06 00:08:46 +00006027 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006028
Eric Snow59032962018-09-14 14:17:20 -07006029 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6030 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6031 return NULL;
6032 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006033 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 pid = fork1();
6035 if (pid == 0) {
6036 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006037 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 } else {
6039 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006040 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 }
6042 if (pid == -1)
6043 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006044 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006045}
Larry Hastings2f936352014-08-05 14:04:04 +10006046#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006047
6048
Guido van Rossumad0ee831995-03-01 10:34:45 +00006049#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006050/*[clinic input]
6051os.fork
6052
6053Fork a child process.
6054
6055Return 0 to child process and PID of child to parent process.
6056[clinic start generated code]*/
6057
Larry Hastings2f936352014-08-05 14:04:04 +10006058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006059os_fork_impl(PyObject *module)
6060/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006061{
Victor Stinner8c62be82010-05-06 00:08:46 +00006062 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006063
Eric Snow59032962018-09-14 14:17:20 -07006064 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6065 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6066 return NULL;
6067 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006068 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 pid = fork();
6070 if (pid == 0) {
6071 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006072 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006073 } else {
6074 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006075 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006076 }
6077 if (pid == -1)
6078 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006080}
Larry Hastings2f936352014-08-05 14:04:04 +10006081#endif /* HAVE_FORK */
6082
Guido van Rossum85e3b011991-06-03 12:42:10 +00006083
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006084#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006085#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006086/*[clinic input]
6087os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006088
Larry Hastings2f936352014-08-05 14:04:04 +10006089 policy: int
6090
6091Get the maximum scheduling priority for policy.
6092[clinic start generated code]*/
6093
Larry Hastings2f936352014-08-05 14:04:04 +10006094static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006095os_sched_get_priority_max_impl(PyObject *module, int policy)
6096/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006097{
6098 int max;
6099
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006100 max = sched_get_priority_max(policy);
6101 if (max < 0)
6102 return posix_error();
6103 return PyLong_FromLong(max);
6104}
6105
Larry Hastings2f936352014-08-05 14:04:04 +10006106
6107/*[clinic input]
6108os.sched_get_priority_min
6109
6110 policy: int
6111
6112Get the minimum scheduling priority for policy.
6113[clinic start generated code]*/
6114
Larry Hastings2f936352014-08-05 14:04:04 +10006115static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006116os_sched_get_priority_min_impl(PyObject *module, int policy)
6117/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006118{
6119 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006120 if (min < 0)
6121 return posix_error();
6122 return PyLong_FromLong(min);
6123}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006124#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6125
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006126
Larry Hastings2f936352014-08-05 14:04:04 +10006127#ifdef HAVE_SCHED_SETSCHEDULER
6128/*[clinic input]
6129os.sched_getscheduler
6130 pid: pid_t
6131 /
6132
Min ho Kimc4cacc82019-07-31 08:16:13 +10006133Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006134
6135Passing 0 for pid returns the scheduling policy for the calling process.
6136[clinic start generated code]*/
6137
Larry Hastings2f936352014-08-05 14:04:04 +10006138static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006139os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006140/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006141{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006142 int policy;
6143
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006144 policy = sched_getscheduler(pid);
6145 if (policy < 0)
6146 return posix_error();
6147 return PyLong_FromLong(policy);
6148}
Larry Hastings2f936352014-08-05 14:04:04 +10006149#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006150
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006151
William Orr81574b82018-10-01 22:19:56 -07006152#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006153/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006154class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006155
6156@classmethod
6157os.sched_param.__new__
6158
6159 sched_priority: object
6160 A scheduling parameter.
6161
6162Current has only one field: sched_priority");
6163[clinic start generated code]*/
6164
Larry Hastings2f936352014-08-05 14:04:04 +10006165static PyObject *
6166os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006167/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006168{
6169 PyObject *res;
6170
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006171 res = PyStructSequence_New(type);
6172 if (!res)
6173 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006174 Py_INCREF(sched_priority);
6175 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006176 return res;
6177}
6178
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006179
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006180PyDoc_VAR(os_sched_param__doc__);
6181
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006182static PyStructSequence_Field sched_param_fields[] = {
6183 {"sched_priority", "the scheduling priority"},
6184 {0}
6185};
6186
6187static PyStructSequence_Desc sched_param_desc = {
6188 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006189 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006190 sched_param_fields,
6191 1
6192};
6193
6194static int
6195convert_sched_param(PyObject *param, struct sched_param *res)
6196{
6197 long priority;
6198
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006199 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006200 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6201 return 0;
6202 }
6203 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6204 if (priority == -1 && PyErr_Occurred())
6205 return 0;
6206 if (priority > INT_MAX || priority < INT_MIN) {
6207 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6208 return 0;
6209 }
6210 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6211 return 1;
6212}
William Orr81574b82018-10-01 22:19:56 -07006213#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006214
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006215
6216#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006217/*[clinic input]
6218os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006219
Larry Hastings2f936352014-08-05 14:04:04 +10006220 pid: pid_t
6221 policy: int
6222 param: sched_param
6223 /
6224
6225Set the scheduling policy for the process identified by pid.
6226
6227If pid is 0, the calling process is changed.
6228param is an instance of sched_param.
6229[clinic start generated code]*/
6230
Larry Hastings2f936352014-08-05 14:04:04 +10006231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006232os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006233 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006234/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006235{
Jesus Cea9c822272011-09-10 01:40:52 +02006236 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006237 ** sched_setscheduler() returns 0 in Linux, but the previous
6238 ** scheduling policy under Solaris/Illumos, and others.
6239 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006240 */
Larry Hastings2f936352014-08-05 14:04:04 +10006241 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006242 return posix_error();
6243 Py_RETURN_NONE;
6244}
Larry Hastings2f936352014-08-05 14:04:04 +10006245#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006246
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006247
6248#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006249/*[clinic input]
6250os.sched_getparam
6251 pid: pid_t
6252 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006253
Larry Hastings2f936352014-08-05 14:04:04 +10006254Returns scheduling parameters for the process identified by pid.
6255
6256If pid is 0, returns parameters for the calling process.
6257Return value is an instance of sched_param.
6258[clinic start generated code]*/
6259
Larry Hastings2f936352014-08-05 14:04:04 +10006260static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006261os_sched_getparam_impl(PyObject *module, pid_t pid)
6262/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006263{
6264 struct sched_param param;
6265 PyObject *result;
6266 PyObject *priority;
6267
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006268 if (sched_getparam(pid, &param))
6269 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006270 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006271 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006272 return NULL;
6273 priority = PyLong_FromLong(param.sched_priority);
6274 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006275 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006276 return NULL;
6277 }
Larry Hastings2f936352014-08-05 14:04:04 +10006278 PyStructSequence_SET_ITEM(result, 0, priority);
6279 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006280}
6281
Larry Hastings2f936352014-08-05 14:04:04 +10006282
6283/*[clinic input]
6284os.sched_setparam
6285 pid: pid_t
6286 param: sched_param
6287 /
6288
6289Set scheduling parameters for the process identified by pid.
6290
6291If pid is 0, sets parameters for the calling process.
6292param should be an instance of sched_param.
6293[clinic start generated code]*/
6294
Larry Hastings2f936352014-08-05 14:04:04 +10006295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006296os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006297 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006298/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006299{
6300 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006301 return posix_error();
6302 Py_RETURN_NONE;
6303}
Larry Hastings2f936352014-08-05 14:04:04 +10006304#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006305
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006306
6307#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006308/*[clinic input]
6309os.sched_rr_get_interval -> double
6310 pid: pid_t
6311 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006312
Larry Hastings2f936352014-08-05 14:04:04 +10006313Return the round-robin quantum for the process identified by pid, in seconds.
6314
6315Value returned is a float.
6316[clinic start generated code]*/
6317
Larry Hastings2f936352014-08-05 14:04:04 +10006318static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006319os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6320/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006321{
6322 struct timespec interval;
6323 if (sched_rr_get_interval(pid, &interval)) {
6324 posix_error();
6325 return -1.0;
6326 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006327#ifdef _Py_MEMORY_SANITIZER
6328 __msan_unpoison(&interval, sizeof(interval));
6329#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006330 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6331}
6332#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006333
Larry Hastings2f936352014-08-05 14:04:04 +10006334
6335/*[clinic input]
6336os.sched_yield
6337
6338Voluntarily relinquish the CPU.
6339[clinic start generated code]*/
6340
Larry Hastings2f936352014-08-05 14:04:04 +10006341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006342os_sched_yield_impl(PyObject *module)
6343/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006344{
6345 if (sched_yield())
6346 return posix_error();
6347 Py_RETURN_NONE;
6348}
6349
Benjamin Peterson2740af82011-08-02 17:41:34 -05006350#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006351/* The minimum number of CPUs allocated in a cpu_set_t */
6352static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006353
Larry Hastings2f936352014-08-05 14:04:04 +10006354/*[clinic input]
6355os.sched_setaffinity
6356 pid: pid_t
6357 mask : object
6358 /
6359
6360Set the CPU affinity of the process identified by pid to mask.
6361
6362mask should be an iterable of integers identifying CPUs.
6363[clinic start generated code]*/
6364
Larry Hastings2f936352014-08-05 14:04:04 +10006365static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006366os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6367/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006368{
Antoine Pitrou84869872012-08-04 16:16:35 +02006369 int ncpus;
6370 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006371 cpu_set_t *cpu_set = NULL;
6372 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006373
Larry Hastings2f936352014-08-05 14:04:04 +10006374 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006375 if (iterator == NULL)
6376 return NULL;
6377
6378 ncpus = NCPUS_START;
6379 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006380 cpu_set = CPU_ALLOC(ncpus);
6381 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006382 PyErr_NoMemory();
6383 goto error;
6384 }
Larry Hastings2f936352014-08-05 14:04:04 +10006385 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006386
6387 while ((item = PyIter_Next(iterator))) {
6388 long cpu;
6389 if (!PyLong_Check(item)) {
6390 PyErr_Format(PyExc_TypeError,
6391 "expected an iterator of ints, "
6392 "but iterator yielded %R",
6393 Py_TYPE(item));
6394 Py_DECREF(item);
6395 goto error;
6396 }
6397 cpu = PyLong_AsLong(item);
6398 Py_DECREF(item);
6399 if (cpu < 0) {
6400 if (!PyErr_Occurred())
6401 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6402 goto error;
6403 }
6404 if (cpu > INT_MAX - 1) {
6405 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6406 goto error;
6407 }
6408 if (cpu >= ncpus) {
6409 /* Grow CPU mask to fit the CPU number */
6410 int newncpus = ncpus;
6411 cpu_set_t *newmask;
6412 size_t newsetsize;
6413 while (newncpus <= cpu) {
6414 if (newncpus > INT_MAX / 2)
6415 newncpus = cpu + 1;
6416 else
6417 newncpus = newncpus * 2;
6418 }
6419 newmask = CPU_ALLOC(newncpus);
6420 if (newmask == NULL) {
6421 PyErr_NoMemory();
6422 goto error;
6423 }
6424 newsetsize = CPU_ALLOC_SIZE(newncpus);
6425 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006426 memcpy(newmask, cpu_set, setsize);
6427 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006428 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006429 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006430 ncpus = newncpus;
6431 }
Larry Hastings2f936352014-08-05 14:04:04 +10006432 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006433 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006434 if (PyErr_Occurred()) {
6435 goto error;
6436 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006437 Py_CLEAR(iterator);
6438
Larry Hastings2f936352014-08-05 14:04:04 +10006439 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006440 posix_error();
6441 goto error;
6442 }
Larry Hastings2f936352014-08-05 14:04:04 +10006443 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006444 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006445
6446error:
Larry Hastings2f936352014-08-05 14:04:04 +10006447 if (cpu_set)
6448 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006449 Py_XDECREF(iterator);
6450 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006451}
6452
Larry Hastings2f936352014-08-05 14:04:04 +10006453
6454/*[clinic input]
6455os.sched_getaffinity
6456 pid: pid_t
6457 /
6458
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006459Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006460
6461The affinity is returned as a set of CPU identifiers.
6462[clinic start generated code]*/
6463
Larry Hastings2f936352014-08-05 14:04:04 +10006464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006465os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006466/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006467{
Antoine Pitrou84869872012-08-04 16:16:35 +02006468 int cpu, ncpus, count;
6469 size_t setsize;
6470 cpu_set_t *mask = NULL;
6471 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006472
Antoine Pitrou84869872012-08-04 16:16:35 +02006473 ncpus = NCPUS_START;
6474 while (1) {
6475 setsize = CPU_ALLOC_SIZE(ncpus);
6476 mask = CPU_ALLOC(ncpus);
6477 if (mask == NULL)
6478 return PyErr_NoMemory();
6479 if (sched_getaffinity(pid, setsize, mask) == 0)
6480 break;
6481 CPU_FREE(mask);
6482 if (errno != EINVAL)
6483 return posix_error();
6484 if (ncpus > INT_MAX / 2) {
6485 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6486 "a large enough CPU set");
6487 return NULL;
6488 }
6489 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006490 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006491
6492 res = PySet_New(NULL);
6493 if (res == NULL)
6494 goto error;
6495 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6496 if (CPU_ISSET_S(cpu, setsize, mask)) {
6497 PyObject *cpu_num = PyLong_FromLong(cpu);
6498 --count;
6499 if (cpu_num == NULL)
6500 goto error;
6501 if (PySet_Add(res, cpu_num)) {
6502 Py_DECREF(cpu_num);
6503 goto error;
6504 }
6505 Py_DECREF(cpu_num);
6506 }
6507 }
6508 CPU_FREE(mask);
6509 return res;
6510
6511error:
6512 if (mask)
6513 CPU_FREE(mask);
6514 Py_XDECREF(res);
6515 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006516}
6517
Benjamin Peterson2740af82011-08-02 17:41:34 -05006518#endif /* HAVE_SCHED_SETAFFINITY */
6519
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006520#endif /* HAVE_SCHED_H */
6521
Larry Hastings2f936352014-08-05 14:04:04 +10006522
Neal Norwitzb59798b2003-03-21 01:43:31 +00006523/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006524/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6525#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006526#define DEV_PTY_FILE "/dev/ptc"
6527#define HAVE_DEV_PTMX
6528#else
6529#define DEV_PTY_FILE "/dev/ptmx"
6530#endif
6531
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006532#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006533#ifdef HAVE_PTY_H
6534#include <pty.h>
6535#else
6536#ifdef HAVE_LIBUTIL_H
6537#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006538#else
6539#ifdef HAVE_UTIL_H
6540#include <util.h>
6541#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006542#endif /* HAVE_LIBUTIL_H */
6543#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006544#ifdef HAVE_STROPTS_H
6545#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006546#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006547#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006548
Larry Hastings2f936352014-08-05 14:04:04 +10006549
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006550#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006551/*[clinic input]
6552os.openpty
6553
6554Open a pseudo-terminal.
6555
6556Return a tuple of (master_fd, slave_fd) containing open file descriptors
6557for both the master and slave ends.
6558[clinic start generated code]*/
6559
Larry Hastings2f936352014-08-05 14:04:04 +10006560static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006561os_openpty_impl(PyObject *module)
6562/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006563{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006564 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006565#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006567#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006568#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006570#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006572#endif
6573#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006574
Thomas Wouters70c21a12000-07-14 14:28:33 +00006575#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006577 goto posix_error;
6578
6579 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6580 goto error;
6581 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6582 goto error;
6583
Neal Norwitzb59798b2003-03-21 01:43:31 +00006584#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6586 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006587 goto posix_error;
6588 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6589 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006590
Victor Stinnerdaf45552013-08-28 00:53:59 +02006591 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006593 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006594
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006595#else
Victor Stinner000de532013-11-25 23:19:58 +01006596 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006598 goto posix_error;
6599
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006601
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 /* change permission of slave */
6603 if (grantpt(master_fd) < 0) {
6604 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006605 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006606 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006607
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 /* unlock slave */
6609 if (unlockpt(master_fd) < 0) {
6610 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006611 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006613
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006615
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 slave_name = ptsname(master_fd); /* get name of slave */
6617 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006618 goto posix_error;
6619
6620 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006621 if (slave_fd == -1)
6622 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006623
6624 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6625 goto posix_error;
6626
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006627#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6629 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006630#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006632#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006633#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006634#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006635
Victor Stinner8c62be82010-05-06 00:08:46 +00006636 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006637
Victor Stinnerdaf45552013-08-28 00:53:59 +02006638posix_error:
6639 posix_error();
6640error:
6641 if (master_fd != -1)
6642 close(master_fd);
6643 if (slave_fd != -1)
6644 close(slave_fd);
6645 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006646}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006647#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006648
Larry Hastings2f936352014-08-05 14:04:04 +10006649
Fred Drake8cef4cf2000-06-28 16:40:38 +00006650#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006651/*[clinic input]
6652os.forkpty
6653
6654Fork a new process with a new pseudo-terminal as controlling tty.
6655
6656Returns a tuple of (pid, master_fd).
6657Like fork(), return pid of 0 to the child process,
6658and pid of child to the parent process.
6659To both, return fd of newly opened pseudo-terminal.
6660[clinic start generated code]*/
6661
Larry Hastings2f936352014-08-05 14:04:04 +10006662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006663os_forkpty_impl(PyObject *module)
6664/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006665{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006666 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006668
Eric Snow59032962018-09-14 14:17:20 -07006669 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6670 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6671 return NULL;
6672 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006673 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 pid = forkpty(&master_fd, NULL, NULL, NULL);
6675 if (pid == 0) {
6676 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006677 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 } else {
6679 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006680 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006681 }
6682 if (pid == -1)
6683 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006685}
Larry Hastings2f936352014-08-05 14:04:04 +10006686#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006687
Ross Lagerwall7807c352011-03-17 20:20:30 +02006688
Guido van Rossumad0ee831995-03-01 10:34:45 +00006689#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006690/*[clinic input]
6691os.getegid
6692
6693Return the current process's effective group id.
6694[clinic start generated code]*/
6695
Larry Hastings2f936352014-08-05 14:04:04 +10006696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006697os_getegid_impl(PyObject *module)
6698/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006699{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006700 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006701}
Larry Hastings2f936352014-08-05 14:04:04 +10006702#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006704
Guido van Rossumad0ee831995-03-01 10:34:45 +00006705#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006706/*[clinic input]
6707os.geteuid
6708
6709Return the current process's effective user id.
6710[clinic start generated code]*/
6711
Larry Hastings2f936352014-08-05 14:04:04 +10006712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006713os_geteuid_impl(PyObject *module)
6714/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006715{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006716 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006717}
Larry Hastings2f936352014-08-05 14:04:04 +10006718#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006720
Guido van Rossumad0ee831995-03-01 10:34:45 +00006721#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006722/*[clinic input]
6723os.getgid
6724
6725Return the current process's group id.
6726[clinic start generated code]*/
6727
Larry Hastings2f936352014-08-05 14:04:04 +10006728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006729os_getgid_impl(PyObject *module)
6730/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006731{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006732 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006733}
Larry Hastings2f936352014-08-05 14:04:04 +10006734#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006736
Berker Peksag39404992016-09-15 20:45:16 +03006737#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006738/*[clinic input]
6739os.getpid
6740
6741Return the current process id.
6742[clinic start generated code]*/
6743
Larry Hastings2f936352014-08-05 14:04:04 +10006744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006745os_getpid_impl(PyObject *module)
6746/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006747{
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006749}
Berker Peksag39404992016-09-15 20:45:16 +03006750#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006751
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006752#ifdef NGROUPS_MAX
6753#define MAX_GROUPS NGROUPS_MAX
6754#else
6755 /* defined to be 16 on Solaris7, so this should be a small number */
6756#define MAX_GROUPS 64
6757#endif
6758
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006759#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006760
6761/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006762PyDoc_STRVAR(posix_getgrouplist__doc__,
6763"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6764Returns a list of groups to which a user belongs.\n\n\
6765 user: username to lookup\n\
6766 group: base group id of the user");
6767
6768static PyObject *
6769posix_getgrouplist(PyObject *self, PyObject *args)
6770{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006771 const char *user;
6772 int i, ngroups;
6773 PyObject *list;
6774#ifdef __APPLE__
6775 int *groups, basegid;
6776#else
6777 gid_t *groups, basegid;
6778#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006779
6780 /*
6781 * NGROUPS_MAX is defined by POSIX.1 as the maximum
6782 * number of supplimental groups a users can belong to.
6783 * We have to increment it by one because
6784 * getgrouplist() returns both the supplemental groups
6785 * and the primary group, i.e. all of the groups the
6786 * user belongs to.
6787 */
6788 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006789
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006790#ifdef __APPLE__
6791 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006792 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006793#else
6794 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6795 _Py_Gid_Converter, &basegid))
6796 return NULL;
6797#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006798
6799#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006800 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006801#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006802 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006803#endif
6804 if (groups == NULL)
6805 return PyErr_NoMemory();
6806
6807 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6808 PyMem_Del(groups);
6809 return posix_error();
6810 }
6811
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006812#ifdef _Py_MEMORY_SANITIZER
6813 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6814 __msan_unpoison(&ngroups, sizeof(ngroups));
6815 __msan_unpoison(groups, ngroups*sizeof(*groups));
6816#endif
6817
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006818 list = PyList_New(ngroups);
6819 if (list == NULL) {
6820 PyMem_Del(groups);
6821 return NULL;
6822 }
6823
6824 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006825#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006826 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006827#else
6828 PyObject *o = _PyLong_FromGid(groups[i]);
6829#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006830 if (o == NULL) {
6831 Py_DECREF(list);
6832 PyMem_Del(groups);
6833 return NULL;
6834 }
6835 PyList_SET_ITEM(list, i, o);
6836 }
6837
6838 PyMem_Del(groups);
6839
6840 return list;
6841}
Larry Hastings2f936352014-08-05 14:04:04 +10006842#endif /* HAVE_GETGROUPLIST */
6843
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006844
Fred Drakec9680921999-12-13 16:37:25 +00006845#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006846/*[clinic input]
6847os.getgroups
6848
6849Return list of supplemental group IDs for the process.
6850[clinic start generated code]*/
6851
Larry Hastings2f936352014-08-05 14:04:04 +10006852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006853os_getgroups_impl(PyObject *module)
6854/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006855{
6856 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006858
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006859 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006860 * This is a helper variable to store the intermediate result when
6861 * that happens.
6862 *
6863 * To keep the code readable the OSX behaviour is unconditional,
6864 * according to the POSIX spec this should be safe on all unix-y
6865 * systems.
6866 */
6867 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006869
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006870#ifdef __APPLE__
6871 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6872 * there are more groups than can fit in grouplist. Therefore, on OS X
6873 * always first call getgroups with length 0 to get the actual number
6874 * of groups.
6875 */
6876 n = getgroups(0, NULL);
6877 if (n < 0) {
6878 return posix_error();
6879 } else if (n <= MAX_GROUPS) {
6880 /* groups will fit in existing array */
6881 alt_grouplist = grouplist;
6882 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006883 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006884 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006885 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006886 }
6887 }
6888
6889 n = getgroups(n, alt_grouplist);
6890 if (n == -1) {
6891 if (alt_grouplist != grouplist) {
6892 PyMem_Free(alt_grouplist);
6893 }
6894 return posix_error();
6895 }
6896#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006898 if (n < 0) {
6899 if (errno == EINVAL) {
6900 n = getgroups(0, NULL);
6901 if (n == -1) {
6902 return posix_error();
6903 }
6904 if (n == 0) {
6905 /* Avoid malloc(0) */
6906 alt_grouplist = grouplist;
6907 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006908 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006909 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006910 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006911 }
6912 n = getgroups(n, alt_grouplist);
6913 if (n == -1) {
6914 PyMem_Free(alt_grouplist);
6915 return posix_error();
6916 }
6917 }
6918 } else {
6919 return posix_error();
6920 }
6921 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006922#endif
6923
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006924 result = PyList_New(n);
6925 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 int i;
6927 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006928 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006930 Py_DECREF(result);
6931 result = NULL;
6932 break;
Fred Drakec9680921999-12-13 16:37:25 +00006933 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006935 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006936 }
6937
6938 if (alt_grouplist != grouplist) {
6939 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006941
Fred Drakec9680921999-12-13 16:37:25 +00006942 return result;
6943}
Larry Hastings2f936352014-08-05 14:04:04 +10006944#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006945
Antoine Pitroub7572f02009-12-02 20:46:48 +00006946#ifdef HAVE_INITGROUPS
6947PyDoc_STRVAR(posix_initgroups__doc__,
6948"initgroups(username, gid) -> None\n\n\
6949Call the system initgroups() to initialize the group access list with all of\n\
6950the groups of which the specified username is a member, plus the specified\n\
6951group id.");
6952
Larry Hastings2f936352014-08-05 14:04:04 +10006953/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006954static PyObject *
6955posix_initgroups(PyObject *self, PyObject *args)
6956{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006957 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006958 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006959 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006960#ifdef __APPLE__
6961 int gid;
6962#else
6963 gid_t gid;
6964#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006965
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006966#ifdef __APPLE__
6967 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6968 PyUnicode_FSConverter, &oname,
6969 &gid))
6970#else
6971 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6972 PyUnicode_FSConverter, &oname,
6973 _Py_Gid_Converter, &gid))
6974#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006976 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006977
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006978 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006979 Py_DECREF(oname);
6980 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006981 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006982
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006983 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006984}
Larry Hastings2f936352014-08-05 14:04:04 +10006985#endif /* HAVE_INITGROUPS */
6986
Antoine Pitroub7572f02009-12-02 20:46:48 +00006987
Martin v. Löwis606edc12002-06-13 21:09:11 +00006988#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006989/*[clinic input]
6990os.getpgid
6991
6992 pid: pid_t
6993
6994Call the system call getpgid(), and return the result.
6995[clinic start generated code]*/
6996
Larry Hastings2f936352014-08-05 14:04:04 +10006997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006998os_getpgid_impl(PyObject *module, pid_t pid)
6999/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007000{
7001 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007002 if (pgid < 0)
7003 return posix_error();
7004 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007005}
7006#endif /* HAVE_GETPGID */
7007
7008
Guido van Rossumb6775db1994-08-01 11:34:53 +00007009#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007010/*[clinic input]
7011os.getpgrp
7012
7013Return the current process group id.
7014[clinic start generated code]*/
7015
Larry Hastings2f936352014-08-05 14:04:04 +10007016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007017os_getpgrp_impl(PyObject *module)
7018/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007019{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007020#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007022#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007023 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007024#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007025}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007026#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007028
Guido van Rossumb6775db1994-08-01 11:34:53 +00007029#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007030/*[clinic input]
7031os.setpgrp
7032
7033Make the current process the leader of its process group.
7034[clinic start generated code]*/
7035
Larry Hastings2f936352014-08-05 14:04:04 +10007036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007037os_setpgrp_impl(PyObject *module)
7038/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007039{
Guido van Rossum64933891994-10-20 21:56:42 +00007040#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007041 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007042#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007044#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007046 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007047}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007048#endif /* HAVE_SETPGRP */
7049
Guido van Rossumad0ee831995-03-01 10:34:45 +00007050#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007051
7052#ifdef MS_WINDOWS
7053#include <tlhelp32.h>
7054
7055static PyObject*
7056win32_getppid()
7057{
7058 HANDLE snapshot;
7059 pid_t mypid;
7060 PyObject* result = NULL;
7061 BOOL have_record;
7062 PROCESSENTRY32 pe;
7063
7064 mypid = getpid(); /* This function never fails */
7065
7066 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7067 if (snapshot == INVALID_HANDLE_VALUE)
7068 return PyErr_SetFromWindowsErr(GetLastError());
7069
7070 pe.dwSize = sizeof(pe);
7071 have_record = Process32First(snapshot, &pe);
7072 while (have_record) {
7073 if (mypid == (pid_t)pe.th32ProcessID) {
7074 /* We could cache the ulong value in a static variable. */
7075 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7076 break;
7077 }
7078
7079 have_record = Process32Next(snapshot, &pe);
7080 }
7081
7082 /* If our loop exits and our pid was not found (result will be NULL)
7083 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7084 * error anyway, so let's raise it. */
7085 if (!result)
7086 result = PyErr_SetFromWindowsErr(GetLastError());
7087
7088 CloseHandle(snapshot);
7089
7090 return result;
7091}
7092#endif /*MS_WINDOWS*/
7093
Larry Hastings2f936352014-08-05 14:04:04 +10007094
7095/*[clinic input]
7096os.getppid
7097
7098Return the parent's process id.
7099
7100If the parent process has already exited, Windows machines will still
7101return its id; others systems will return the id of the 'init' process (1).
7102[clinic start generated code]*/
7103
Larry Hastings2f936352014-08-05 14:04:04 +10007104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007105os_getppid_impl(PyObject *module)
7106/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007107{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007108#ifdef MS_WINDOWS
7109 return win32_getppid();
7110#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007112#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007113}
7114#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007115
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007116
Fred Drake12c6e2d1999-12-14 21:25:03 +00007117#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007118/*[clinic input]
7119os.getlogin
7120
7121Return the actual login name.
7122[clinic start generated code]*/
7123
Larry Hastings2f936352014-08-05 14:04:04 +10007124static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007125os_getlogin_impl(PyObject *module)
7126/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007127{
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007129#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007130 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007131 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007132
7133 if (GetUserNameW(user_name, &num_chars)) {
7134 /* num_chars is the number of unicode chars plus null terminator */
7135 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007136 }
7137 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007138 result = PyErr_SetFromWindowsErr(GetLastError());
7139#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007140 char *name;
7141 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007142
Victor Stinner8c62be82010-05-06 00:08:46 +00007143 errno = 0;
7144 name = getlogin();
7145 if (name == NULL) {
7146 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007147 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007148 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007149 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 }
7151 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007152 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007154#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007155 return result;
7156}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007157#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007158
Larry Hastings2f936352014-08-05 14:04:04 +10007159
Guido van Rossumad0ee831995-03-01 10:34:45 +00007160#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007161/*[clinic input]
7162os.getuid
7163
7164Return the current process's user id.
7165[clinic start generated code]*/
7166
Larry Hastings2f936352014-08-05 14:04:04 +10007167static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007168os_getuid_impl(PyObject *module)
7169/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007170{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007171 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007172}
Larry Hastings2f936352014-08-05 14:04:04 +10007173#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007175
Brian Curtineb24d742010-04-12 17:16:38 +00007176#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007177#define HAVE_KILL
7178#endif /* MS_WINDOWS */
7179
7180#ifdef HAVE_KILL
7181/*[clinic input]
7182os.kill
7183
7184 pid: pid_t
7185 signal: Py_ssize_t
7186 /
7187
7188Kill a process with a signal.
7189[clinic start generated code]*/
7190
Larry Hastings2f936352014-08-05 14:04:04 +10007191static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007192os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7193/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007194#ifndef MS_WINDOWS
7195{
7196 if (kill(pid, (int)signal) == -1)
7197 return posix_error();
7198 Py_RETURN_NONE;
7199}
7200#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007201{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007202 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007203 DWORD sig = (DWORD)signal;
7204 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007206
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 /* Console processes which share a common console can be sent CTRL+C or
7208 CTRL+BREAK events, provided they handle said events. */
7209 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007210 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 err = GetLastError();
7212 PyErr_SetFromWindowsErr(err);
7213 }
7214 else
7215 Py_RETURN_NONE;
7216 }
Brian Curtineb24d742010-04-12 17:16:38 +00007217
Victor Stinner8c62be82010-05-06 00:08:46 +00007218 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7219 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007220 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007221 if (handle == NULL) {
7222 err = GetLastError();
7223 return PyErr_SetFromWindowsErr(err);
7224 }
Brian Curtineb24d742010-04-12 17:16:38 +00007225
Victor Stinner8c62be82010-05-06 00:08:46 +00007226 if (TerminateProcess(handle, sig) == 0) {
7227 err = GetLastError();
7228 result = PyErr_SetFromWindowsErr(err);
7229 } else {
7230 Py_INCREF(Py_None);
7231 result = Py_None;
7232 }
Brian Curtineb24d742010-04-12 17:16:38 +00007233
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 CloseHandle(handle);
7235 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007236}
Larry Hastings2f936352014-08-05 14:04:04 +10007237#endif /* !MS_WINDOWS */
7238#endif /* HAVE_KILL */
7239
7240
7241#ifdef HAVE_KILLPG
7242/*[clinic input]
7243os.killpg
7244
7245 pgid: pid_t
7246 signal: int
7247 /
7248
7249Kill a process group with a signal.
7250[clinic start generated code]*/
7251
Larry Hastings2f936352014-08-05 14:04:04 +10007252static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007253os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7254/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007255{
7256 /* XXX some man pages make the `pgid` parameter an int, others
7257 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7258 take the same type. Moreover, pid_t is always at least as wide as
7259 int (else compilation of this module fails), which is safe. */
7260 if (killpg(pgid, signal) == -1)
7261 return posix_error();
7262 Py_RETURN_NONE;
7263}
7264#endif /* HAVE_KILLPG */
7265
Brian Curtineb24d742010-04-12 17:16:38 +00007266
Guido van Rossumc0125471996-06-28 18:55:32 +00007267#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007268#ifdef HAVE_SYS_LOCK_H
7269#include <sys/lock.h>
7270#endif
7271
Larry Hastings2f936352014-08-05 14:04:04 +10007272/*[clinic input]
7273os.plock
7274 op: int
7275 /
7276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007277Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007278[clinic start generated code]*/
7279
Larry Hastings2f936352014-08-05 14:04:04 +10007280static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007281os_plock_impl(PyObject *module, int op)
7282/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007283{
Victor Stinner8c62be82010-05-06 00:08:46 +00007284 if (plock(op) == -1)
7285 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007286 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007287}
Larry Hastings2f936352014-08-05 14:04:04 +10007288#endif /* HAVE_PLOCK */
7289
Guido van Rossumc0125471996-06-28 18:55:32 +00007290
Guido van Rossumb6775db1994-08-01 11:34:53 +00007291#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007292/*[clinic input]
7293os.setuid
7294
7295 uid: uid_t
7296 /
7297
7298Set the current process's user id.
7299[clinic start generated code]*/
7300
Larry Hastings2f936352014-08-05 14:04:04 +10007301static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007302os_setuid_impl(PyObject *module, uid_t uid)
7303/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007304{
Victor Stinner8c62be82010-05-06 00:08:46 +00007305 if (setuid(uid) < 0)
7306 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007307 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007308}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007309#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007311
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007312#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007313/*[clinic input]
7314os.seteuid
7315
7316 euid: uid_t
7317 /
7318
7319Set the current process's effective user id.
7320[clinic start generated code]*/
7321
Larry Hastings2f936352014-08-05 14:04:04 +10007322static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007323os_seteuid_impl(PyObject *module, uid_t euid)
7324/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007325{
7326 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007327 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007328 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007329}
7330#endif /* HAVE_SETEUID */
7331
Larry Hastings2f936352014-08-05 14:04:04 +10007332
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007333#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007334/*[clinic input]
7335os.setegid
7336
7337 egid: gid_t
7338 /
7339
7340Set the current process's effective group id.
7341[clinic start generated code]*/
7342
Larry Hastings2f936352014-08-05 14:04:04 +10007343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007344os_setegid_impl(PyObject *module, gid_t egid)
7345/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007346{
7347 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007348 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007349 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007350}
7351#endif /* HAVE_SETEGID */
7352
Larry Hastings2f936352014-08-05 14:04:04 +10007353
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007354#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007355/*[clinic input]
7356os.setreuid
7357
7358 ruid: uid_t
7359 euid: uid_t
7360 /
7361
7362Set the current process's real and effective user ids.
7363[clinic start generated code]*/
7364
Larry Hastings2f936352014-08-05 14:04:04 +10007365static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007366os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7367/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007368{
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 if (setreuid(ruid, euid) < 0) {
7370 return posix_error();
7371 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007372 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007373 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007374}
7375#endif /* HAVE_SETREUID */
7376
Larry Hastings2f936352014-08-05 14:04:04 +10007377
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007378#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007379/*[clinic input]
7380os.setregid
7381
7382 rgid: gid_t
7383 egid: gid_t
7384 /
7385
7386Set the current process's real and effective group ids.
7387[clinic start generated code]*/
7388
Larry Hastings2f936352014-08-05 14:04:04 +10007389static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007390os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7391/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007392{
7393 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007394 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007395 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007396}
7397#endif /* HAVE_SETREGID */
7398
Larry Hastings2f936352014-08-05 14:04:04 +10007399
Guido van Rossumb6775db1994-08-01 11:34:53 +00007400#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007401/*[clinic input]
7402os.setgid
7403 gid: gid_t
7404 /
7405
7406Set the current process's group id.
7407[clinic start generated code]*/
7408
Larry Hastings2f936352014-08-05 14:04:04 +10007409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007410os_setgid_impl(PyObject *module, gid_t gid)
7411/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007412{
Victor Stinner8c62be82010-05-06 00:08:46 +00007413 if (setgid(gid) < 0)
7414 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007415 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007416}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007417#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007418
Larry Hastings2f936352014-08-05 14:04:04 +10007419
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007420#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007421/*[clinic input]
7422os.setgroups
7423
7424 groups: object
7425 /
7426
7427Set the groups of the current process to list.
7428[clinic start generated code]*/
7429
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007431os_setgroups(PyObject *module, PyObject *groups)
7432/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007433{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007434 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007436
Victor Stinner8c62be82010-05-06 00:08:46 +00007437 if (!PySequence_Check(groups)) {
7438 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7439 return NULL;
7440 }
7441 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007442 if (len < 0) {
7443 return NULL;
7444 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007445 if (len > MAX_GROUPS) {
7446 PyErr_SetString(PyExc_ValueError, "too many groups");
7447 return NULL;
7448 }
7449 for(i = 0; i < len; i++) {
7450 PyObject *elem;
7451 elem = PySequence_GetItem(groups, i);
7452 if (!elem)
7453 return NULL;
7454 if (!PyLong_Check(elem)) {
7455 PyErr_SetString(PyExc_TypeError,
7456 "groups must be integers");
7457 Py_DECREF(elem);
7458 return NULL;
7459 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007460 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007461 Py_DECREF(elem);
7462 return NULL;
7463 }
7464 }
7465 Py_DECREF(elem);
7466 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007467
Victor Stinner8c62be82010-05-06 00:08:46 +00007468 if (setgroups(len, grouplist) < 0)
7469 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007470 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007471}
7472#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007473
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007474#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7475static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007476wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007477{
Victor Stinner8c62be82010-05-06 00:08:46 +00007478 PyObject *result;
7479 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007480 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007481
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 if (pid == -1)
7483 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007484
Victor Stinner8c62be82010-05-06 00:08:46 +00007485 if (struct_rusage == NULL) {
7486 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7487 if (m == NULL)
7488 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007489 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007490 Py_DECREF(m);
7491 if (struct_rusage == NULL)
7492 return NULL;
7493 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007494
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7496 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7497 if (!result)
7498 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007499
7500#ifndef doubletime
7501#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7502#endif
7503
Victor Stinner8c62be82010-05-06 00:08:46 +00007504 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007505 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007506 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007507 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007508#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007509 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7510 SET_INT(result, 2, ru->ru_maxrss);
7511 SET_INT(result, 3, ru->ru_ixrss);
7512 SET_INT(result, 4, ru->ru_idrss);
7513 SET_INT(result, 5, ru->ru_isrss);
7514 SET_INT(result, 6, ru->ru_minflt);
7515 SET_INT(result, 7, ru->ru_majflt);
7516 SET_INT(result, 8, ru->ru_nswap);
7517 SET_INT(result, 9, ru->ru_inblock);
7518 SET_INT(result, 10, ru->ru_oublock);
7519 SET_INT(result, 11, ru->ru_msgsnd);
7520 SET_INT(result, 12, ru->ru_msgrcv);
7521 SET_INT(result, 13, ru->ru_nsignals);
7522 SET_INT(result, 14, ru->ru_nvcsw);
7523 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007524#undef SET_INT
7525
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 if (PyErr_Occurred()) {
7527 Py_DECREF(result);
7528 return NULL;
7529 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007530
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007532}
7533#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7534
Larry Hastings2f936352014-08-05 14:04:04 +10007535
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007536#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007537/*[clinic input]
7538os.wait3
7539
7540 options: int
7541Wait for completion of a child process.
7542
7543Returns a tuple of information about the child process:
7544 (pid, status, rusage)
7545[clinic start generated code]*/
7546
Larry Hastings2f936352014-08-05 14:04:04 +10007547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007548os_wait3_impl(PyObject *module, int options)
7549/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007550{
Victor Stinner8c62be82010-05-06 00:08:46 +00007551 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007552 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007553 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 WAIT_TYPE status;
7555 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007556
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007557 do {
7558 Py_BEGIN_ALLOW_THREADS
7559 pid = wait3(&status, options, &ru);
7560 Py_END_ALLOW_THREADS
7561 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7562 if (pid < 0)
7563 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007564
Victor Stinner4195b5c2012-02-08 23:03:19 +01007565 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007566}
7567#endif /* HAVE_WAIT3 */
7568
Larry Hastings2f936352014-08-05 14:04:04 +10007569
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007570#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007571/*[clinic input]
7572
7573os.wait4
7574
7575 pid: pid_t
7576 options: int
7577
7578Wait for completion of a specific child process.
7579
7580Returns a tuple of information about the child process:
7581 (pid, status, rusage)
7582[clinic start generated code]*/
7583
Larry Hastings2f936352014-08-05 14:04:04 +10007584static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007585os_wait4_impl(PyObject *module, pid_t pid, int options)
7586/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007587{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007588 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007589 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007590 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007591 WAIT_TYPE status;
7592 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007593
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007594 do {
7595 Py_BEGIN_ALLOW_THREADS
7596 res = wait4(pid, &status, options, &ru);
7597 Py_END_ALLOW_THREADS
7598 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7599 if (res < 0)
7600 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007601
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007602 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007603}
7604#endif /* HAVE_WAIT4 */
7605
Larry Hastings2f936352014-08-05 14:04:04 +10007606
Ross Lagerwall7807c352011-03-17 20:20:30 +02007607#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007608/*[clinic input]
7609os.waitid
7610
7611 idtype: idtype_t
7612 Must be one of be P_PID, P_PGID or P_ALL.
7613 id: id_t
7614 The id to wait on.
7615 options: int
7616 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7617 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7618 /
7619
7620Returns the result of waiting for a process or processes.
7621
7622Returns either waitid_result or None if WNOHANG is specified and there are
7623no children in a waitable state.
7624[clinic start generated code]*/
7625
Larry Hastings2f936352014-08-05 14:04:04 +10007626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007627os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7628/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007629{
7630 PyObject *result;
7631 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007632 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007633 siginfo_t si;
7634 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007635
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007636 do {
7637 Py_BEGIN_ALLOW_THREADS
7638 res = waitid(idtype, id, &si, options);
7639 Py_END_ALLOW_THREADS
7640 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7641 if (res < 0)
7642 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007643
7644 if (si.si_pid == 0)
7645 Py_RETURN_NONE;
7646
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007647 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007648 if (!result)
7649 return NULL;
7650
7651 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007652 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007653 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7654 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7655 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7656 if (PyErr_Occurred()) {
7657 Py_DECREF(result);
7658 return NULL;
7659 }
7660
7661 return result;
7662}
Larry Hastings2f936352014-08-05 14:04:04 +10007663#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007664
Larry Hastings2f936352014-08-05 14:04:04 +10007665
7666#if defined(HAVE_WAITPID)
7667/*[clinic input]
7668os.waitpid
7669 pid: pid_t
7670 options: int
7671 /
7672
7673Wait for completion of a given child process.
7674
7675Returns a tuple of information regarding the child process:
7676 (pid, status)
7677
7678The options argument is ignored on Windows.
7679[clinic start generated code]*/
7680
Larry Hastings2f936352014-08-05 14:04:04 +10007681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007682os_waitpid_impl(PyObject *module, pid_t pid, int options)
7683/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007684{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007685 pid_t res;
7686 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 WAIT_TYPE status;
7688 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007689
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007690 do {
7691 Py_BEGIN_ALLOW_THREADS
7692 res = waitpid(pid, &status, options);
7693 Py_END_ALLOW_THREADS
7694 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7695 if (res < 0)
7696 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007697
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007698 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007699}
Tim Petersab034fa2002-02-01 11:27:43 +00007700#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007701/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007702/*[clinic input]
7703os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007704 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007705 options: int
7706 /
7707
7708Wait for completion of a given process.
7709
7710Returns a tuple of information regarding the process:
7711 (pid, status << 8)
7712
7713The options argument is ignored on Windows.
7714[clinic start generated code]*/
7715
Larry Hastings2f936352014-08-05 14:04:04 +10007716static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007717os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007718/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007719{
7720 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007721 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007722 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007723
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007724 do {
7725 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007726 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007728 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007729 Py_END_ALLOW_THREADS
7730 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007731 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007732 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007733
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007735 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007736}
Larry Hastings2f936352014-08-05 14:04:04 +10007737#endif
7738
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007739
Guido van Rossumad0ee831995-03-01 10:34:45 +00007740#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007741/*[clinic input]
7742os.wait
7743
7744Wait for completion of a child process.
7745
7746Returns a tuple of information about the child process:
7747 (pid, status)
7748[clinic start generated code]*/
7749
Larry Hastings2f936352014-08-05 14:04:04 +10007750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007751os_wait_impl(PyObject *module)
7752/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007753{
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007755 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 WAIT_TYPE status;
7757 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007758
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007759 do {
7760 Py_BEGIN_ALLOW_THREADS
7761 pid = wait(&status);
7762 Py_END_ALLOW_THREADS
7763 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7764 if (pid < 0)
7765 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007766
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007768}
Larry Hastings2f936352014-08-05 14:04:04 +10007769#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007770
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007771
Larry Hastings9cf065c2012-06-22 16:30:09 -07007772#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007773/*[clinic input]
7774os.readlink
7775
7776 path: path_t
7777 *
7778 dir_fd: dir_fd(requires='readlinkat') = None
7779
7780Return a string representing the path to which the symbolic link points.
7781
7782If dir_fd is not None, it should be a file descriptor open to a directory,
7783and path should be relative; path will then be relative to that directory.
7784
7785dir_fd may not be implemented on your platform. If it is unavailable,
7786using it will raise a NotImplementedError.
7787[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007788
Barry Warsaw53699e91996-12-10 23:23:01 +00007789static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007790os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7791/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007792{
Berker Peksage0b5b202018-08-15 13:03:41 +03007793#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007794 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007795 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007796
7797 Py_BEGIN_ALLOW_THREADS
7798#ifdef HAVE_READLINKAT
7799 if (dir_fd != DEFAULT_DIR_FD)
7800 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7801 else
7802#endif
7803 length = readlink(path->narrow, buffer, MAXPATHLEN);
7804 Py_END_ALLOW_THREADS
7805
7806 if (length < 0) {
7807 return path_error(path);
7808 }
7809 buffer[length] = '\0';
7810
7811 if (PyUnicode_Check(path->object))
7812 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7813 else
7814 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007815#elif defined(MS_WINDOWS)
7816 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007817 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03007818 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007819 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7820 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007821 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007822
Larry Hastings2f936352014-08-05 14:04:04 +10007823 /* First get a handle to the reparse point */
7824 Py_BEGIN_ALLOW_THREADS
7825 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007826 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007827 0,
7828 0,
7829 0,
7830 OPEN_EXISTING,
7831 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7832 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007833 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
7834 /* New call DeviceIoControl to read the reparse point */
7835 io_result = DeviceIoControl(
7836 reparse_point_handle,
7837 FSCTL_GET_REPARSE_POINT,
7838 0, 0, /* in buffer */
7839 target_buffer, sizeof(target_buffer),
7840 &n_bytes_returned,
7841 0 /* we're not using OVERLAPPED_IO */
7842 );
7843 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03007844 }
Larry Hastings2f936352014-08-05 14:04:04 +10007845 Py_END_ALLOW_THREADS
7846
Berker Peksage0b5b202018-08-15 13:03:41 +03007847 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007848 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007849 }
Larry Hastings2f936352014-08-05 14:04:04 +10007850
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007851 wchar_t *name = NULL;
7852 Py_ssize_t nameLen = 0;
7853 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10007854 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007855 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7856 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
7857 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10007858 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07007859 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
7860 {
7861 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
7862 rdb->MountPointReparseBuffer.SubstituteNameOffset);
7863 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
7864 }
7865 else
7866 {
7867 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
7868 }
7869 if (name) {
7870 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
7871 /* Our buffer is mutable, so this is okay */
7872 name[1] = L'\\';
7873 }
7874 result = PyUnicode_FromWideChar(name, nameLen);
7875 if (path->narrow) {
7876 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
7877 }
Berker Peksage0b5b202018-08-15 13:03:41 +03007878 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007879 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007880#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007881}
Berker Peksage0b5b202018-08-15 13:03:41 +03007882#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007883
Larry Hastings9cf065c2012-06-22 16:30:09 -07007884#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007885
7886#if defined(MS_WINDOWS)
7887
Steve Dower6921e732018-03-05 14:26:08 -08007888/* Remove the last portion of the path - return 0 on success */
7889static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007890_dirnameW(WCHAR *path)
7891{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007892 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007893 size_t length = wcsnlen_s(path, MAX_PATH);
7894 if (length == MAX_PATH) {
7895 return -1;
7896 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007897
7898 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007899 for(ptr = path + length; ptr != path; ptr--) {
7900 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007901 break;
Steve Dower6921e732018-03-05 14:26:08 -08007902 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007903 }
7904 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007905 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007906}
7907
Victor Stinner31b3b922013-06-05 01:49:17 +02007908/* Is this path absolute? */
7909static int
7910_is_absW(const WCHAR *path)
7911{
Steve Dower6921e732018-03-05 14:26:08 -08007912 return path[0] == L'\\' || path[0] == L'/' ||
7913 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007914}
7915
Steve Dower6921e732018-03-05 14:26:08 -08007916/* join root and rest with a backslash - return 0 on success */
7917static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007918_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7919{
Victor Stinner31b3b922013-06-05 01:49:17 +02007920 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007921 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007922 }
7923
Steve Dower6921e732018-03-05 14:26:08 -08007924 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7925 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007926 }
Steve Dower6921e732018-03-05 14:26:08 -08007927
7928 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7929 return -1;
7930 }
7931
7932 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007933}
7934
Victor Stinner31b3b922013-06-05 01:49:17 +02007935/* Return True if the path at src relative to dest is a directory */
7936static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007937_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007938{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007939 WIN32_FILE_ATTRIBUTE_DATA src_info;
7940 WCHAR dest_parent[MAX_PATH];
7941 WCHAR src_resolved[MAX_PATH] = L"";
7942
7943 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007944 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7945 _dirnameW(dest_parent)) {
7946 return 0;
7947 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007948 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007949 if (_joinW(src_resolved, dest_parent, src)) {
7950 return 0;
7951 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007952 return (
7953 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7954 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7955 );
7956}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007957#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007958
Larry Hastings2f936352014-08-05 14:04:04 +10007959
7960/*[clinic input]
7961os.symlink
7962 src: path_t
7963 dst: path_t
7964 target_is_directory: bool = False
7965 *
7966 dir_fd: dir_fd(requires='symlinkat')=None
7967
7968# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7969
7970Create a symbolic link pointing to src named dst.
7971
7972target_is_directory is required on Windows if the target is to be
7973 interpreted as a directory. (On Windows, symlink requires
7974 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7975 target_is_directory is ignored on non-Windows platforms.
7976
7977If dir_fd is not None, it should be a file descriptor open to a directory,
7978 and path should be relative; path will then be relative to that directory.
7979dir_fd may not be implemented on your platform.
7980 If it is unavailable, using it will raise a NotImplementedError.
7981
7982[clinic start generated code]*/
7983
Larry Hastings2f936352014-08-05 14:04:04 +10007984static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007985os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007986 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007987/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007988{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007989#ifdef MS_WINDOWS
7990 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007991 DWORD flags = 0;
7992
7993 /* Assumed true, set to false if detected to not be available. */
7994 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007995#else
7996 int result;
7997#endif
7998
Larry Hastings9cf065c2012-06-22 16:30:09 -07007999#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008000
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008001 if (windows_has_symlink_unprivileged_flag) {
8002 /* Allow non-admin symlinks if system allows it. */
8003 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8004 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008005
Larry Hastings9cf065c2012-06-22 16:30:09 -07008006 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008007 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008008 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8009 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8010 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8011 }
8012
8013 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008014 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008015 Py_END_ALLOW_THREADS
8016
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008017 if (windows_has_symlink_unprivileged_flag && !result &&
8018 ERROR_INVALID_PARAMETER == GetLastError()) {
8019
8020 Py_BEGIN_ALLOW_THREADS
8021 _Py_BEGIN_SUPPRESS_IPH
8022 /* This error might be caused by
8023 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8024 Try again, and update windows_has_symlink_unprivileged_flag if we
8025 are successful this time.
8026
8027 NOTE: There is a risk of a race condition here if there are other
8028 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8029 another process (or thread) changes that condition in between our
8030 calls to CreateSymbolicLink.
8031 */
8032 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8033 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8034 _Py_END_SUPPRESS_IPH
8035 Py_END_ALLOW_THREADS
8036
8037 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8038 windows_has_symlink_unprivileged_flag = FALSE;
8039 }
8040 }
8041
Larry Hastings2f936352014-08-05 14:04:04 +10008042 if (!result)
8043 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008044
8045#else
8046
Steve Dower6921e732018-03-05 14:26:08 -08008047 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8048 PyErr_SetString(PyExc_ValueError,
8049 "symlink: src and dst must be the same type");
8050 return NULL;
8051 }
8052
Larry Hastings9cf065c2012-06-22 16:30:09 -07008053 Py_BEGIN_ALLOW_THREADS
8054#if HAVE_SYMLINKAT
8055 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008056 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008057 else
8058#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008059 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008060 Py_END_ALLOW_THREADS
8061
Larry Hastings2f936352014-08-05 14:04:04 +10008062 if (result)
8063 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008064#endif
8065
Larry Hastings2f936352014-08-05 14:04:04 +10008066 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008067}
8068#endif /* HAVE_SYMLINK */
8069
Larry Hastings9cf065c2012-06-22 16:30:09 -07008070
Brian Curtind40e6f72010-07-08 21:39:08 +00008071
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008072
Larry Hastings605a62d2012-06-24 04:33:36 -07008073static PyStructSequence_Field times_result_fields[] = {
8074 {"user", "user time"},
8075 {"system", "system time"},
8076 {"children_user", "user time of children"},
8077 {"children_system", "system time of children"},
8078 {"elapsed", "elapsed time since an arbitrary point in the past"},
8079 {NULL}
8080};
8081
8082PyDoc_STRVAR(times_result__doc__,
8083"times_result: Result from os.times().\n\n\
8084This object may be accessed either as a tuple of\n\
8085 (user, system, children_user, children_system, elapsed),\n\
8086or via the attributes user, system, children_user, children_system,\n\
8087and elapsed.\n\
8088\n\
8089See os.times for more information.");
8090
8091static PyStructSequence_Desc times_result_desc = {
8092 "times_result", /* name */
8093 times_result__doc__, /* doc */
8094 times_result_fields,
8095 5
8096};
8097
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008098static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07008099
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008100#ifdef MS_WINDOWS
8101#define HAVE_TIMES /* mandatory, for the method table */
8102#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008103
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008104#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008105
8106static PyObject *
8107build_times_result(double user, double system,
8108 double children_user, double children_system,
8109 double elapsed)
8110{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08008111 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008112 if (value == NULL)
8113 return NULL;
8114
8115#define SET(i, field) \
8116 { \
8117 PyObject *o = PyFloat_FromDouble(field); \
8118 if (!o) { \
8119 Py_DECREF(value); \
8120 return NULL; \
8121 } \
8122 PyStructSequence_SET_ITEM(value, i, o); \
8123 } \
8124
8125 SET(0, user);
8126 SET(1, system);
8127 SET(2, children_user);
8128 SET(3, children_system);
8129 SET(4, elapsed);
8130
8131#undef SET
8132
8133 return value;
8134}
8135
Larry Hastings605a62d2012-06-24 04:33:36 -07008136
Larry Hastings2f936352014-08-05 14:04:04 +10008137#ifndef MS_WINDOWS
8138#define NEED_TICKS_PER_SECOND
8139static long ticks_per_second = -1;
8140#endif /* MS_WINDOWS */
8141
8142/*[clinic input]
8143os.times
8144
8145Return a collection containing process timing information.
8146
8147The object returned behaves like a named tuple with these fields:
8148 (utime, stime, cutime, cstime, elapsed_time)
8149All fields are floating point numbers.
8150[clinic start generated code]*/
8151
Larry Hastings2f936352014-08-05 14:04:04 +10008152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008153os_times_impl(PyObject *module)
8154/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008155#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008156{
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 FILETIME create, exit, kernel, user;
8158 HANDLE hProc;
8159 hProc = GetCurrentProcess();
8160 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8161 /* The fields of a FILETIME structure are the hi and lo part
8162 of a 64-bit value expressed in 100 nanosecond units.
8163 1e7 is one second in such units; 1e-7 the inverse.
8164 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8165 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008166 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 (double)(user.dwHighDateTime*429.4967296 +
8168 user.dwLowDateTime*1e-7),
8169 (double)(kernel.dwHighDateTime*429.4967296 +
8170 kernel.dwLowDateTime*1e-7),
8171 (double)0,
8172 (double)0,
8173 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008174}
Larry Hastings2f936352014-08-05 14:04:04 +10008175#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008176{
Larry Hastings2f936352014-08-05 14:04:04 +10008177
8178
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008179 struct tms t;
8180 clock_t c;
8181 errno = 0;
8182 c = times(&t);
8183 if (c == (clock_t) -1)
8184 return posix_error();
8185 return build_times_result(
8186 (double)t.tms_utime / ticks_per_second,
8187 (double)t.tms_stime / ticks_per_second,
8188 (double)t.tms_cutime / ticks_per_second,
8189 (double)t.tms_cstime / ticks_per_second,
8190 (double)c / ticks_per_second);
8191}
Larry Hastings2f936352014-08-05 14:04:04 +10008192#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008193#endif /* HAVE_TIMES */
8194
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008195
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008196#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008197/*[clinic input]
8198os.getsid
8199
8200 pid: pid_t
8201 /
8202
8203Call the system call getsid(pid) and return the result.
8204[clinic start generated code]*/
8205
Larry Hastings2f936352014-08-05 14:04:04 +10008206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008207os_getsid_impl(PyObject *module, pid_t pid)
8208/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008209{
Victor Stinner8c62be82010-05-06 00:08:46 +00008210 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 sid = getsid(pid);
8212 if (sid < 0)
8213 return posix_error();
8214 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008215}
8216#endif /* HAVE_GETSID */
8217
8218
Guido van Rossumb6775db1994-08-01 11:34:53 +00008219#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008220/*[clinic input]
8221os.setsid
8222
8223Call the system call setsid().
8224[clinic start generated code]*/
8225
Larry Hastings2f936352014-08-05 14:04:04 +10008226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008227os_setsid_impl(PyObject *module)
8228/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008229{
Victor Stinner8c62be82010-05-06 00:08:46 +00008230 if (setsid() < 0)
8231 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008232 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008233}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008234#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008235
Larry Hastings2f936352014-08-05 14:04:04 +10008236
Guido van Rossumb6775db1994-08-01 11:34:53 +00008237#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008238/*[clinic input]
8239os.setpgid
8240
8241 pid: pid_t
8242 pgrp: pid_t
8243 /
8244
8245Call the system call setpgid(pid, pgrp).
8246[clinic start generated code]*/
8247
Larry Hastings2f936352014-08-05 14:04:04 +10008248static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008249os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8250/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008251{
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 if (setpgid(pid, pgrp) < 0)
8253 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008254 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008255}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008256#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008258
Guido van Rossumb6775db1994-08-01 11:34:53 +00008259#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008260/*[clinic input]
8261os.tcgetpgrp
8262
8263 fd: int
8264 /
8265
8266Return the process group associated with the terminal specified by fd.
8267[clinic start generated code]*/
8268
Larry Hastings2f936352014-08-05 14:04:04 +10008269static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008270os_tcgetpgrp_impl(PyObject *module, int fd)
8271/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008272{
8273 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 if (pgid < 0)
8275 return posix_error();
8276 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008277}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008278#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008280
Guido van Rossumb6775db1994-08-01 11:34:53 +00008281#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008282/*[clinic input]
8283os.tcsetpgrp
8284
8285 fd: int
8286 pgid: pid_t
8287 /
8288
8289Set the process group associated with the terminal specified by fd.
8290[clinic start generated code]*/
8291
Larry Hastings2f936352014-08-05 14:04:04 +10008292static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008293os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8294/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008295{
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 if (tcsetpgrp(fd, pgid) < 0)
8297 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008298 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008299}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008300#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008301
Guido van Rossum687dd131993-05-17 08:34:16 +00008302/* Functions acting on file descriptors */
8303
Victor Stinnerdaf45552013-08-28 00:53:59 +02008304#ifdef O_CLOEXEC
8305extern int _Py_open_cloexec_works;
8306#endif
8307
Larry Hastings2f936352014-08-05 14:04:04 +10008308
8309/*[clinic input]
8310os.open -> int
8311 path: path_t
8312 flags: int
8313 mode: int = 0o777
8314 *
8315 dir_fd: dir_fd(requires='openat') = None
8316
8317# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8318
8319Open a file for low level IO. Returns a file descriptor (integer).
8320
8321If dir_fd is not None, it should be a file descriptor open to a directory,
8322 and path should be relative; path will then be relative to that directory.
8323dir_fd may not be implemented on your platform.
8324 If it is unavailable, using it will raise a NotImplementedError.
8325[clinic start generated code]*/
8326
Larry Hastings2f936352014-08-05 14:04:04 +10008327static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008328os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8329/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008330{
8331 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008332 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008333
Victor Stinnerdaf45552013-08-28 00:53:59 +02008334#ifdef O_CLOEXEC
8335 int *atomic_flag_works = &_Py_open_cloexec_works;
8336#elif !defined(MS_WINDOWS)
8337 int *atomic_flag_works = NULL;
8338#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008339
Victor Stinnerdaf45552013-08-28 00:53:59 +02008340#ifdef MS_WINDOWS
8341 flags |= O_NOINHERIT;
8342#elif defined(O_CLOEXEC)
8343 flags |= O_CLOEXEC;
8344#endif
8345
Steve Dowerb82e17e2019-05-23 08:45:22 -07008346 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8347 return -1;
8348 }
8349
Steve Dower8fc89802015-04-12 00:26:27 -04008350 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008351 do {
8352 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008353#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008354 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008355#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008356#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008357 if (dir_fd != DEFAULT_DIR_FD)
8358 fd = openat(dir_fd, path->narrow, flags, mode);
8359 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008360#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008361 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008362#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008363 Py_END_ALLOW_THREADS
8364 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008365 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008366
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008367 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008368 if (!async_err)
8369 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008370 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008371 }
8372
Victor Stinnerdaf45552013-08-28 00:53:59 +02008373#ifndef MS_WINDOWS
8374 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8375 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008376 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008377 }
8378#endif
8379
Larry Hastings2f936352014-08-05 14:04:04 +10008380 return fd;
8381}
8382
8383
8384/*[clinic input]
8385os.close
8386
8387 fd: int
8388
8389Close a file descriptor.
8390[clinic start generated code]*/
8391
Barry Warsaw53699e91996-12-10 23:23:01 +00008392static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008393os_close_impl(PyObject *module, int fd)
8394/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008395{
Larry Hastings2f936352014-08-05 14:04:04 +10008396 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008397 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8398 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8399 * for more details.
8400 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008402 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008404 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 Py_END_ALLOW_THREADS
8406 if (res < 0)
8407 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008408 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008409}
8410
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008411
Larry Hastings2f936352014-08-05 14:04:04 +10008412/*[clinic input]
8413os.closerange
8414
8415 fd_low: int
8416 fd_high: int
8417 /
8418
8419Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8420[clinic start generated code]*/
8421
Larry Hastings2f936352014-08-05 14:04:04 +10008422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008423os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8424/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008425{
8426 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008428 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008429 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008430 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008431 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008432 Py_END_ALLOW_THREADS
8433 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008434}
8435
8436
Larry Hastings2f936352014-08-05 14:04:04 +10008437/*[clinic input]
8438os.dup -> int
8439
8440 fd: int
8441 /
8442
8443Return a duplicate of a file descriptor.
8444[clinic start generated code]*/
8445
Larry Hastings2f936352014-08-05 14:04:04 +10008446static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008447os_dup_impl(PyObject *module, int fd)
8448/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008449{
8450 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008451}
8452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008453
Larry Hastings2f936352014-08-05 14:04:04 +10008454/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008455os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008456 fd: int
8457 fd2: int
8458 inheritable: bool=True
8459
8460Duplicate file descriptor.
8461[clinic start generated code]*/
8462
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008463static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008464os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008465/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008466{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008467 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008468#if defined(HAVE_DUP3) && \
8469 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8470 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008471 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008472#endif
8473
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008474 if (fd < 0 || fd2 < 0) {
8475 posix_error();
8476 return -1;
8477 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008478
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008479 /* dup2() can fail with EINTR if the target FD is already open, because it
8480 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8481 * upon close(), and therefore below.
8482 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008483#ifdef MS_WINDOWS
8484 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008485 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008486 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008487 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008488 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008489 if (res < 0) {
8490 posix_error();
8491 return -1;
8492 }
8493 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008494
8495 /* Character files like console cannot be make non-inheritable */
8496 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8497 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008498 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008499 }
8500
8501#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8502 Py_BEGIN_ALLOW_THREADS
8503 if (!inheritable)
8504 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8505 else
8506 res = dup2(fd, fd2);
8507 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008508 if (res < 0) {
8509 posix_error();
8510 return -1;
8511 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008512
8513#else
8514
8515#ifdef HAVE_DUP3
8516 if (!inheritable && dup3_works != 0) {
8517 Py_BEGIN_ALLOW_THREADS
8518 res = dup3(fd, fd2, O_CLOEXEC);
8519 Py_END_ALLOW_THREADS
8520 if (res < 0) {
8521 if (dup3_works == -1)
8522 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008523 if (dup3_works) {
8524 posix_error();
8525 return -1;
8526 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008527 }
8528 }
8529
8530 if (inheritable || dup3_works == 0)
8531 {
8532#endif
8533 Py_BEGIN_ALLOW_THREADS
8534 res = dup2(fd, fd2);
8535 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008536 if (res < 0) {
8537 posix_error();
8538 return -1;
8539 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008540
8541 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8542 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008543 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008544 }
8545#ifdef HAVE_DUP3
8546 }
8547#endif
8548
8549#endif
8550
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008551 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008552}
8553
Larry Hastings2f936352014-08-05 14:04:04 +10008554
Ross Lagerwall7807c352011-03-17 20:20:30 +02008555#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008556/*[clinic input]
8557os.lockf
8558
8559 fd: int
8560 An open file descriptor.
8561 command: int
8562 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8563 length: Py_off_t
8564 The number of bytes to lock, starting at the current position.
8565 /
8566
8567Apply, test or remove a POSIX lock on an open file descriptor.
8568
8569[clinic start generated code]*/
8570
Larry Hastings2f936352014-08-05 14:04:04 +10008571static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008572os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8573/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008574{
8575 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008576
8577 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008578 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008579 Py_END_ALLOW_THREADS
8580
8581 if (res < 0)
8582 return posix_error();
8583
8584 Py_RETURN_NONE;
8585}
Larry Hastings2f936352014-08-05 14:04:04 +10008586#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008587
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008588
Larry Hastings2f936352014-08-05 14:04:04 +10008589/*[clinic input]
8590os.lseek -> Py_off_t
8591
8592 fd: int
8593 position: Py_off_t
8594 how: int
8595 /
8596
8597Set the position of a file descriptor. Return the new position.
8598
8599Return the new cursor position in number of bytes
8600relative to the beginning of the file.
8601[clinic start generated code]*/
8602
Larry Hastings2f936352014-08-05 14:04:04 +10008603static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008604os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8605/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008606{
8607 Py_off_t result;
8608
Guido van Rossum687dd131993-05-17 08:34:16 +00008609#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8611 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008612 case 0: how = SEEK_SET; break;
8613 case 1: how = SEEK_CUR; break;
8614 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008616#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008617
Victor Stinner8c62be82010-05-06 00:08:46 +00008618 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008619 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008620#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008621 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008622#else
Larry Hastings2f936352014-08-05 14:04:04 +10008623 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008624#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008625 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008627 if (result < 0)
8628 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008629
Larry Hastings2f936352014-08-05 14:04:04 +10008630 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008631}
8632
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008633
Larry Hastings2f936352014-08-05 14:04:04 +10008634/*[clinic input]
8635os.read
8636 fd: int
8637 length: Py_ssize_t
8638 /
8639
8640Read from a file descriptor. Returns a bytes object.
8641[clinic start generated code]*/
8642
Larry Hastings2f936352014-08-05 14:04:04 +10008643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008644os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8645/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008646{
Victor Stinner8c62be82010-05-06 00:08:46 +00008647 Py_ssize_t n;
8648 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008649
8650 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008651 errno = EINVAL;
8652 return posix_error();
8653 }
Larry Hastings2f936352014-08-05 14:04:04 +10008654
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008655 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008656
8657 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 if (buffer == NULL)
8659 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008660
Victor Stinner66aab0c2015-03-19 22:53:20 +01008661 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8662 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008663 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008664 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008665 }
Larry Hastings2f936352014-08-05 14:04:04 +10008666
8667 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008668 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008669
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008671}
8672
Ross Lagerwall7807c352011-03-17 20:20:30 +02008673#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008674 || defined(__APPLE__))) \
8675 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8676 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8677static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008678iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008679{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008680 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008681
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008682 *iov = PyMem_New(struct iovec, cnt);
8683 if (*iov == NULL) {
8684 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008685 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008686 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008687
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008688 *buf = PyMem_New(Py_buffer, cnt);
8689 if (*buf == NULL) {
8690 PyMem_Del(*iov);
8691 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008692 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008693 }
8694
8695 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008696 PyObject *item = PySequence_GetItem(seq, i);
8697 if (item == NULL)
8698 goto fail;
8699 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8700 Py_DECREF(item);
8701 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008702 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008703 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008704 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008705 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008706 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008707 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008708
8709fail:
8710 PyMem_Del(*iov);
8711 for (j = 0; j < i; j++) {
8712 PyBuffer_Release(&(*buf)[j]);
8713 }
8714 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008715 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008716}
8717
8718static void
8719iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8720{
8721 int i;
8722 PyMem_Del(iov);
8723 for (i = 0; i < cnt; i++) {
8724 PyBuffer_Release(&buf[i]);
8725 }
8726 PyMem_Del(buf);
8727}
8728#endif
8729
Larry Hastings2f936352014-08-05 14:04:04 +10008730
Ross Lagerwall7807c352011-03-17 20:20:30 +02008731#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008732/*[clinic input]
8733os.readv -> Py_ssize_t
8734
8735 fd: int
8736 buffers: object
8737 /
8738
8739Read from a file descriptor fd into an iterable of buffers.
8740
8741The buffers should be mutable buffers accepting bytes.
8742readv will transfer data into each buffer until it is full
8743and then move on to the next buffer in the sequence to hold
8744the rest of the data.
8745
8746readv returns the total number of bytes read,
8747which may be less than the total capacity of all the buffers.
8748[clinic start generated code]*/
8749
Larry Hastings2f936352014-08-05 14:04:04 +10008750static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008751os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8752/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008753{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008754 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008755 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008756 struct iovec *iov;
8757 Py_buffer *buf;
8758
Larry Hastings2f936352014-08-05 14:04:04 +10008759 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008760 PyErr_SetString(PyExc_TypeError,
8761 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008762 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008763 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008764
Larry Hastings2f936352014-08-05 14:04:04 +10008765 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008766 if (cnt < 0)
8767 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008768
8769 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8770 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008771
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008772 do {
8773 Py_BEGIN_ALLOW_THREADS
8774 n = readv(fd, iov, cnt);
8775 Py_END_ALLOW_THREADS
8776 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008777
8778 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008779 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008780 if (!async_err)
8781 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008782 return -1;
8783 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008784
Larry Hastings2f936352014-08-05 14:04:04 +10008785 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008786}
Larry Hastings2f936352014-08-05 14:04:04 +10008787#endif /* HAVE_READV */
8788
Ross Lagerwall7807c352011-03-17 20:20:30 +02008789
8790#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008791/*[clinic input]
8792# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8793os.pread
8794
8795 fd: int
8796 length: int
8797 offset: Py_off_t
8798 /
8799
8800Read a number of bytes from a file descriptor starting at a particular offset.
8801
8802Read length bytes from file descriptor fd, starting at offset bytes from
8803the beginning of the file. The file offset remains unchanged.
8804[clinic start generated code]*/
8805
Larry Hastings2f936352014-08-05 14:04:04 +10008806static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008807os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8808/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008809{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008810 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008811 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008812 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008813
Larry Hastings2f936352014-08-05 14:04:04 +10008814 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008815 errno = EINVAL;
8816 return posix_error();
8817 }
Larry Hastings2f936352014-08-05 14:04:04 +10008818 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008819 if (buffer == NULL)
8820 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008821
8822 do {
8823 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008824 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008825 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008826 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008827 Py_END_ALLOW_THREADS
8828 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8829
Ross Lagerwall7807c352011-03-17 20:20:30 +02008830 if (n < 0) {
8831 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008832 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008833 }
Larry Hastings2f936352014-08-05 14:04:04 +10008834 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008835 _PyBytes_Resize(&buffer, n);
8836 return buffer;
8837}
Larry Hastings2f936352014-08-05 14:04:04 +10008838#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008839
Pablo Galindo4defba32018-01-27 16:16:37 +00008840#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8841/*[clinic input]
8842os.preadv -> Py_ssize_t
8843
8844 fd: int
8845 buffers: object
8846 offset: Py_off_t
8847 flags: int = 0
8848 /
8849
8850Reads from a file descriptor into a number of mutable bytes-like objects.
8851
8852Combines the functionality of readv() and pread(). As readv(), it will
8853transfer data into each buffer until it is full and then move on to the next
8854buffer in the sequence to hold the rest of the data. Its fourth argument,
8855specifies the file offset at which the input operation is to be performed. It
8856will return the total number of bytes read (which can be less than the total
8857capacity of all the objects).
8858
8859The flags argument contains a bitwise OR of zero or more of the following flags:
8860
8861- RWF_HIPRI
8862- RWF_NOWAIT
8863
8864Using non-zero flags requires Linux 4.6 or newer.
8865[clinic start generated code]*/
8866
8867static Py_ssize_t
8868os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8869 int flags)
8870/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8871{
8872 Py_ssize_t cnt, n;
8873 int async_err = 0;
8874 struct iovec *iov;
8875 Py_buffer *buf;
8876
8877 if (!PySequence_Check(buffers)) {
8878 PyErr_SetString(PyExc_TypeError,
8879 "preadv2() arg 2 must be a sequence");
8880 return -1;
8881 }
8882
8883 cnt = PySequence_Size(buffers);
8884 if (cnt < 0) {
8885 return -1;
8886 }
8887
8888#ifndef HAVE_PREADV2
8889 if(flags != 0) {
8890 argument_unavailable_error("preadv2", "flags");
8891 return -1;
8892 }
8893#endif
8894
8895 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8896 return -1;
8897 }
8898#ifdef HAVE_PREADV2
8899 do {
8900 Py_BEGIN_ALLOW_THREADS
8901 _Py_BEGIN_SUPPRESS_IPH
8902 n = preadv2(fd, iov, cnt, offset, flags);
8903 _Py_END_SUPPRESS_IPH
8904 Py_END_ALLOW_THREADS
8905 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8906#else
8907 do {
8908 Py_BEGIN_ALLOW_THREADS
8909 _Py_BEGIN_SUPPRESS_IPH
8910 n = preadv(fd, iov, cnt, offset);
8911 _Py_END_SUPPRESS_IPH
8912 Py_END_ALLOW_THREADS
8913 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8914#endif
8915
8916 iov_cleanup(iov, buf, cnt);
8917 if (n < 0) {
8918 if (!async_err) {
8919 posix_error();
8920 }
8921 return -1;
8922 }
8923
8924 return n;
8925}
8926#endif /* HAVE_PREADV */
8927
Larry Hastings2f936352014-08-05 14:04:04 +10008928
8929/*[clinic input]
8930os.write -> Py_ssize_t
8931
8932 fd: int
8933 data: Py_buffer
8934 /
8935
8936Write a bytes object to a file descriptor.
8937[clinic start generated code]*/
8938
Larry Hastings2f936352014-08-05 14:04:04 +10008939static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008940os_write_impl(PyObject *module, int fd, Py_buffer *data)
8941/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008942{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008943 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008944}
8945
8946#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008947PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008948"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008949sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008950 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008951Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008952
Larry Hastings2f936352014-08-05 14:04:04 +10008953/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008954static PyObject *
8955posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8956{
8957 int in, out;
8958 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008959 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008960 off_t offset;
8961
8962#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8963#ifndef __APPLE__
8964 Py_ssize_t len;
8965#endif
8966 PyObject *headers = NULL, *trailers = NULL;
8967 Py_buffer *hbuf, *tbuf;
8968 off_t sbytes;
8969 struct sf_hdtr sf;
8970 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008971 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008972 static char *keywords[] = {"out", "in",
8973 "offset", "count",
8974 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008975
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008976 sf.headers = NULL;
8977 sf.trailers = NULL;
8978
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008979#ifdef __APPLE__
8980 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008981 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008982#else
8983 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008984 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008985#endif
8986 &headers, &trailers, &flags))
8987 return NULL;
8988 if (headers != NULL) {
8989 if (!PySequence_Check(headers)) {
8990 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008991 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008992 return NULL;
8993 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008994 Py_ssize_t i = PySequence_Size(headers);
8995 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008996 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008997 if (i > INT_MAX) {
8998 PyErr_SetString(PyExc_OverflowError,
8999 "sendfile() header is too large");
9000 return NULL;
9001 }
9002 if (i > 0) {
9003 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009004 if (iov_setup(&(sf.headers), &hbuf,
9005 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009006 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009007#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009008 for (i = 0; i < sf.hdr_cnt; i++) {
9009 Py_ssize_t blen = sf.headers[i].iov_len;
9010# define OFF_T_MAX 0x7fffffffffffffff
9011 if (sbytes >= OFF_T_MAX - blen) {
9012 PyErr_SetString(PyExc_OverflowError,
9013 "sendfile() header is too large");
9014 return NULL;
9015 }
9016 sbytes += blen;
9017 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009018#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009019 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009020 }
9021 }
9022 if (trailers != NULL) {
9023 if (!PySequence_Check(trailers)) {
9024 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009025 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009026 return NULL;
9027 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009028 Py_ssize_t i = PySequence_Size(trailers);
9029 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009030 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009031 if (i > INT_MAX) {
9032 PyErr_SetString(PyExc_OverflowError,
9033 "sendfile() trailer is too large");
9034 return NULL;
9035 }
9036 if (i > 0) {
9037 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009038 if (iov_setup(&(sf.trailers), &tbuf,
9039 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009040 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009041 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009042 }
9043 }
9044
Steve Dower8fc89802015-04-12 00:26:27 -04009045 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009046 do {
9047 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009048#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009049 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009050#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009051 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009052#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009053 Py_END_ALLOW_THREADS
9054 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009055 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009056
9057 if (sf.headers != NULL)
9058 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9059 if (sf.trailers != NULL)
9060 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9061
9062 if (ret < 0) {
9063 if ((errno == EAGAIN) || (errno == EBUSY)) {
9064 if (sbytes != 0) {
9065 // some data has been sent
9066 goto done;
9067 }
9068 else {
9069 // no data has been sent; upper application is supposed
9070 // to retry on EAGAIN or EBUSY
9071 return posix_error();
9072 }
9073 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009074 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009075 }
9076 goto done;
9077
9078done:
9079 #if !defined(HAVE_LARGEFILE_SUPPORT)
9080 return Py_BuildValue("l", sbytes);
9081 #else
9082 return Py_BuildValue("L", sbytes);
9083 #endif
9084
9085#else
9086 Py_ssize_t count;
9087 PyObject *offobj;
9088 static char *keywords[] = {"out", "in",
9089 "offset", "count", NULL};
9090 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
9091 keywords, &out, &in, &offobj, &count))
9092 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009093#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009094 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009095 do {
9096 Py_BEGIN_ALLOW_THREADS
9097 ret = sendfile(out, in, NULL, count);
9098 Py_END_ALLOW_THREADS
9099 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009100 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009101 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009102 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009103 }
9104#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009105 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009106 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009107
9108 do {
9109 Py_BEGIN_ALLOW_THREADS
9110 ret = sendfile(out, in, &offset, count);
9111 Py_END_ALLOW_THREADS
9112 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009113 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009114 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009115 return Py_BuildValue("n", ret);
9116#endif
9117}
Larry Hastings2f936352014-08-05 14:04:04 +10009118#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009119
Larry Hastings2f936352014-08-05 14:04:04 +10009120
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009121#if defined(__APPLE__)
9122/*[clinic input]
9123os._fcopyfile
9124
9125 infd: int
9126 outfd: int
9127 flags: int
9128 /
9129
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009130Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009131[clinic start generated code]*/
9132
9133static PyObject *
9134os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009135/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009136{
9137 int ret;
9138
9139 Py_BEGIN_ALLOW_THREADS
9140 ret = fcopyfile(infd, outfd, NULL, flags);
9141 Py_END_ALLOW_THREADS
9142 if (ret < 0)
9143 return posix_error();
9144 Py_RETURN_NONE;
9145}
9146#endif
9147
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149/*[clinic input]
9150os.fstat
9151
9152 fd : int
9153
9154Perform a stat system call on the given file descriptor.
9155
9156Like stat(), but for an open file descriptor.
9157Equivalent to os.stat(fd).
9158[clinic start generated code]*/
9159
Larry Hastings2f936352014-08-05 14:04:04 +10009160static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009161os_fstat_impl(PyObject *module, int fd)
9162/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009163{
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 STRUCT_STAT st;
9165 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009166 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009167
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009168 do {
9169 Py_BEGIN_ALLOW_THREADS
9170 res = FSTAT(fd, &st);
9171 Py_END_ALLOW_THREADS
9172 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009173 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009174#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009175 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009176#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009177 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009178#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 }
Tim Peters5aa91602002-01-30 05:46:57 +00009180
Victor Stinner4195b5c2012-02-08 23:03:19 +01009181 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009182}
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184
9185/*[clinic input]
9186os.isatty -> bool
9187 fd: int
9188 /
9189
9190Return True if the fd is connected to a terminal.
9191
9192Return True if the file descriptor is an open file descriptor
9193connected to the slave end of a terminal.
9194[clinic start generated code]*/
9195
Larry Hastings2f936352014-08-05 14:04:04 +10009196static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009197os_isatty_impl(PyObject *module, int fd)
9198/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009199{
Steve Dower8fc89802015-04-12 00:26:27 -04009200 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009201 _Py_BEGIN_SUPPRESS_IPH
9202 return_value = isatty(fd);
9203 _Py_END_SUPPRESS_IPH
9204 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009205}
9206
9207
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009208#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009209/*[clinic input]
9210os.pipe
9211
9212Create a pipe.
9213
9214Returns a tuple of two file descriptors:
9215 (read_fd, write_fd)
9216[clinic start generated code]*/
9217
Larry Hastings2f936352014-08-05 14:04:04 +10009218static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009219os_pipe_impl(PyObject *module)
9220/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009221{
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009225 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009227#else
9228 int res;
9229#endif
9230
9231#ifdef MS_WINDOWS
9232 attr.nLength = sizeof(attr);
9233 attr.lpSecurityDescriptor = NULL;
9234 attr.bInheritHandle = FALSE;
9235
9236 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009237 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009238 ok = CreatePipe(&read, &write, &attr, 0);
9239 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009240 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9241 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009242 if (fds[0] == -1 || fds[1] == -1) {
9243 CloseHandle(read);
9244 CloseHandle(write);
9245 ok = 0;
9246 }
9247 }
Steve Dowerc3630612016-11-19 18:41:16 -08009248 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009249 Py_END_ALLOW_THREADS
9250
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009252 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009253#else
9254
9255#ifdef HAVE_PIPE2
9256 Py_BEGIN_ALLOW_THREADS
9257 res = pipe2(fds, O_CLOEXEC);
9258 Py_END_ALLOW_THREADS
9259
9260 if (res != 0 && errno == ENOSYS)
9261 {
9262#endif
9263 Py_BEGIN_ALLOW_THREADS
9264 res = pipe(fds);
9265 Py_END_ALLOW_THREADS
9266
9267 if (res == 0) {
9268 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9269 close(fds[0]);
9270 close(fds[1]);
9271 return NULL;
9272 }
9273 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9274 close(fds[0]);
9275 close(fds[1]);
9276 return NULL;
9277 }
9278 }
9279#ifdef HAVE_PIPE2
9280 }
9281#endif
9282
9283 if (res != 0)
9284 return PyErr_SetFromErrno(PyExc_OSError);
9285#endif /* !MS_WINDOWS */
9286 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009287}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009288#endif /* HAVE_PIPE */
9289
Larry Hastings2f936352014-08-05 14:04:04 +10009290
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009291#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009292/*[clinic input]
9293os.pipe2
9294
9295 flags: int
9296 /
9297
9298Create a pipe with flags set atomically.
9299
9300Returns a tuple of two file descriptors:
9301 (read_fd, write_fd)
9302
9303flags can be constructed by ORing together one or more of these values:
9304O_NONBLOCK, O_CLOEXEC.
9305[clinic start generated code]*/
9306
Larry Hastings2f936352014-08-05 14:04:04 +10009307static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009308os_pipe2_impl(PyObject *module, int flags)
9309/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009310{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009311 int fds[2];
9312 int res;
9313
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009314 res = pipe2(fds, flags);
9315 if (res != 0)
9316 return posix_error();
9317 return Py_BuildValue("(ii)", fds[0], fds[1]);
9318}
9319#endif /* HAVE_PIPE2 */
9320
Larry Hastings2f936352014-08-05 14:04:04 +10009321
Ross Lagerwall7807c352011-03-17 20:20:30 +02009322#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009323/*[clinic input]
9324os.writev -> Py_ssize_t
9325 fd: int
9326 buffers: object
9327 /
9328
9329Iterate over buffers, and write the contents of each to a file descriptor.
9330
9331Returns the total number of bytes written.
9332buffers must be a sequence of bytes-like objects.
9333[clinic start generated code]*/
9334
Larry Hastings2f936352014-08-05 14:04:04 +10009335static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009336os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9337/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009338{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009339 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009340 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009341 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009342 struct iovec *iov;
9343 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009344
9345 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009346 PyErr_SetString(PyExc_TypeError,
9347 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009348 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009349 }
Larry Hastings2f936352014-08-05 14:04:04 +10009350 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009351 if (cnt < 0)
9352 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009353
Larry Hastings2f936352014-08-05 14:04:04 +10009354 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9355 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009356 }
9357
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009358 do {
9359 Py_BEGIN_ALLOW_THREADS
9360 result = writev(fd, iov, cnt);
9361 Py_END_ALLOW_THREADS
9362 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009363
9364 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009365 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009366 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009367
Georg Brandl306336b2012-06-24 12:55:33 +02009368 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009369}
Larry Hastings2f936352014-08-05 14:04:04 +10009370#endif /* HAVE_WRITEV */
9371
9372
9373#ifdef HAVE_PWRITE
9374/*[clinic input]
9375os.pwrite -> Py_ssize_t
9376
9377 fd: int
9378 buffer: Py_buffer
9379 offset: Py_off_t
9380 /
9381
9382Write bytes to a file descriptor starting at a particular offset.
9383
9384Write buffer to fd, starting at offset bytes from the beginning of
9385the file. Returns the number of bytes writte. Does not change the
9386current file offset.
9387[clinic start generated code]*/
9388
Larry Hastings2f936352014-08-05 14:04:04 +10009389static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009390os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9391/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009392{
9393 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009394 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009395
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009396 do {
9397 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009398 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009399 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009400 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009401 Py_END_ALLOW_THREADS
9402 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009403
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009404 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009405 posix_error();
9406 return size;
9407}
9408#endif /* HAVE_PWRITE */
9409
Pablo Galindo4defba32018-01-27 16:16:37 +00009410#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9411/*[clinic input]
9412os.pwritev -> Py_ssize_t
9413
9414 fd: int
9415 buffers: object
9416 offset: Py_off_t
9417 flags: int = 0
9418 /
9419
9420Writes the contents of bytes-like objects to a file descriptor at a given offset.
9421
9422Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9423of bytes-like objects. Buffers are processed in array order. Entire contents of first
9424buffer is written before proceeding to second, and so on. The operating system may
9425set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9426This function writes the contents of each object to the file descriptor and returns
9427the total number of bytes written.
9428
9429The flags argument contains a bitwise OR of zero or more of the following flags:
9430
9431- RWF_DSYNC
9432- RWF_SYNC
9433
9434Using non-zero flags requires Linux 4.7 or newer.
9435[clinic start generated code]*/
9436
9437static Py_ssize_t
9438os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9439 int flags)
9440/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9441{
9442 Py_ssize_t cnt;
9443 Py_ssize_t result;
9444 int async_err = 0;
9445 struct iovec *iov;
9446 Py_buffer *buf;
9447
9448 if (!PySequence_Check(buffers)) {
9449 PyErr_SetString(PyExc_TypeError,
9450 "pwritev() arg 2 must be a sequence");
9451 return -1;
9452 }
9453
9454 cnt = PySequence_Size(buffers);
9455 if (cnt < 0) {
9456 return -1;
9457 }
9458
9459#ifndef HAVE_PWRITEV2
9460 if(flags != 0) {
9461 argument_unavailable_error("pwritev2", "flags");
9462 return -1;
9463 }
9464#endif
9465
9466 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9467 return -1;
9468 }
9469#ifdef HAVE_PWRITEV2
9470 do {
9471 Py_BEGIN_ALLOW_THREADS
9472 _Py_BEGIN_SUPPRESS_IPH
9473 result = pwritev2(fd, iov, cnt, offset, flags);
9474 _Py_END_SUPPRESS_IPH
9475 Py_END_ALLOW_THREADS
9476 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9477#else
9478 do {
9479 Py_BEGIN_ALLOW_THREADS
9480 _Py_BEGIN_SUPPRESS_IPH
9481 result = pwritev(fd, iov, cnt, offset);
9482 _Py_END_SUPPRESS_IPH
9483 Py_END_ALLOW_THREADS
9484 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9485#endif
9486
9487 iov_cleanup(iov, buf, cnt);
9488 if (result < 0) {
9489 if (!async_err) {
9490 posix_error();
9491 }
9492 return -1;
9493 }
9494
9495 return result;
9496}
9497#endif /* HAVE_PWRITEV */
9498
Pablo Galindoaac4d032019-05-31 19:39:47 +01009499#ifdef HAVE_COPY_FILE_RANGE
9500/*[clinic input]
9501
9502os.copy_file_range
9503 src: int
9504 Source file descriptor.
9505 dst: int
9506 Destination file descriptor.
9507 count: Py_ssize_t
9508 Number of bytes to copy.
9509 offset_src: object = None
9510 Starting offset in src.
9511 offset_dst: object = None
9512 Starting offset in dst.
9513
9514Copy count bytes from one file descriptor to another.
9515
9516If offset_src is None, then src is read from the current position;
9517respectively for offset_dst.
9518[clinic start generated code]*/
9519
9520static PyObject *
9521os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9522 PyObject *offset_src, PyObject *offset_dst)
9523/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9524{
9525 off_t offset_src_val, offset_dst_val;
9526 off_t *p_offset_src = NULL;
9527 off_t *p_offset_dst = NULL;
9528 Py_ssize_t ret;
9529 int async_err = 0;
9530 /* The flags argument is provided to allow
9531 * for future extensions and currently must be to 0. */
9532 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009533
9534
Pablo Galindoaac4d032019-05-31 19:39:47 +01009535 if (count < 0) {
9536 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9537 return NULL;
9538 }
9539
9540 if (offset_src != Py_None) {
9541 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9542 return NULL;
9543 }
9544 p_offset_src = &offset_src_val;
9545 }
9546
9547 if (offset_dst != Py_None) {
9548 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9549 return NULL;
9550 }
9551 p_offset_dst = &offset_dst_val;
9552 }
9553
9554 do {
9555 Py_BEGIN_ALLOW_THREADS
9556 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9557 Py_END_ALLOW_THREADS
9558 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9559
9560 if (ret < 0) {
9561 return (!async_err) ? posix_error() : NULL;
9562 }
9563
9564 return PyLong_FromSsize_t(ret);
9565}
9566#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009567
9568#ifdef HAVE_MKFIFO
9569/*[clinic input]
9570os.mkfifo
9571
9572 path: path_t
9573 mode: int=0o666
9574 *
9575 dir_fd: dir_fd(requires='mkfifoat')=None
9576
9577Create a "fifo" (a POSIX named pipe).
9578
9579If dir_fd is not None, it should be a file descriptor open to a directory,
9580 and path should be relative; path will then be relative to that directory.
9581dir_fd may not be implemented on your platform.
9582 If it is unavailable, using it will raise a NotImplementedError.
9583[clinic start generated code]*/
9584
Larry Hastings2f936352014-08-05 14:04:04 +10009585static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009586os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9587/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009588{
9589 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009590 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009591
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009592 do {
9593 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009594#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009595 if (dir_fd != DEFAULT_DIR_FD)
9596 result = mkfifoat(dir_fd, path->narrow, mode);
9597 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009598#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009599 result = mkfifo(path->narrow, mode);
9600 Py_END_ALLOW_THREADS
9601 } while (result != 0 && errno == EINTR &&
9602 !(async_err = PyErr_CheckSignals()));
9603 if (result != 0)
9604 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009605
9606 Py_RETURN_NONE;
9607}
9608#endif /* HAVE_MKFIFO */
9609
9610
9611#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9612/*[clinic input]
9613os.mknod
9614
9615 path: path_t
9616 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009617 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009618 *
9619 dir_fd: dir_fd(requires='mknodat')=None
9620
9621Create a node in the file system.
9622
9623Create a node in the file system (file, device special file or named pipe)
9624at path. mode specifies both the permissions to use and the
9625type of node to be created, being combined (bitwise OR) with one of
9626S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9627device defines the newly created device special file (probably using
9628os.makedev()). Otherwise device is ignored.
9629
9630If dir_fd is not None, it should be a file descriptor open to a directory,
9631 and path should be relative; path will then be relative to that directory.
9632dir_fd may not be implemented on your platform.
9633 If it is unavailable, using it will raise a NotImplementedError.
9634[clinic start generated code]*/
9635
Larry Hastings2f936352014-08-05 14:04:04 +10009636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009637os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009638 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009639/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009640{
9641 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009642 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009643
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009644 do {
9645 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009646#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009647 if (dir_fd != DEFAULT_DIR_FD)
9648 result = mknodat(dir_fd, path->narrow, mode, device);
9649 else
Larry Hastings2f936352014-08-05 14:04:04 +10009650#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009651 result = mknod(path->narrow, mode, device);
9652 Py_END_ALLOW_THREADS
9653 } while (result != 0 && errno == EINTR &&
9654 !(async_err = PyErr_CheckSignals()));
9655 if (result != 0)
9656 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009657
9658 Py_RETURN_NONE;
9659}
9660#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9661
9662
9663#ifdef HAVE_DEVICE_MACROS
9664/*[clinic input]
9665os.major -> unsigned_int
9666
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009667 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009668 /
9669
9670Extracts a device major number from a raw device number.
9671[clinic start generated code]*/
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009674os_major_impl(PyObject *module, dev_t device)
9675/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009676{
9677 return major(device);
9678}
9679
9680
9681/*[clinic input]
9682os.minor -> unsigned_int
9683
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009684 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009685 /
9686
9687Extracts a device minor number from a raw device number.
9688[clinic start generated code]*/
9689
Larry Hastings2f936352014-08-05 14:04:04 +10009690static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009691os_minor_impl(PyObject *module, dev_t device)
9692/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009693{
9694 return minor(device);
9695}
9696
9697
9698/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009699os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009700
9701 major: int
9702 minor: int
9703 /
9704
9705Composes a raw device number from the major and minor device numbers.
9706[clinic start generated code]*/
9707
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009708static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009709os_makedev_impl(PyObject *module, int major, int minor)
9710/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009711{
9712 return makedev(major, minor);
9713}
9714#endif /* HAVE_DEVICE_MACROS */
9715
9716
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009717#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009718/*[clinic input]
9719os.ftruncate
9720
9721 fd: int
9722 length: Py_off_t
9723 /
9724
9725Truncate a file, specified by file descriptor, to a specific length.
9726[clinic start generated code]*/
9727
Larry Hastings2f936352014-08-05 14:04:04 +10009728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009729os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9730/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009731{
9732 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009733 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009734
Steve Dowerb82e17e2019-05-23 08:45:22 -07009735 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
9736 return NULL;
9737 }
9738
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009739 do {
9740 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009741 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009742#ifdef MS_WINDOWS
9743 result = _chsize_s(fd, length);
9744#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009745 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009746#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009747 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009748 Py_END_ALLOW_THREADS
9749 } while (result != 0 && errno == EINTR &&
9750 !(async_err = PyErr_CheckSignals()));
9751 if (result != 0)
9752 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009753 Py_RETURN_NONE;
9754}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009755#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009756
9757
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009758#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009759/*[clinic input]
9760os.truncate
9761 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9762 length: Py_off_t
9763
9764Truncate a file, specified by path, to a specific length.
9765
9766On some platforms, path may also be specified as an open file descriptor.
9767 If this functionality is unavailable, using it raises an exception.
9768[clinic start generated code]*/
9769
Larry Hastings2f936352014-08-05 14:04:04 +10009770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009771os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9772/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009773{
9774 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009775#ifdef MS_WINDOWS
9776 int fd;
9777#endif
9778
9779 if (path->fd != -1)
9780 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009781
Steve Dowerb82e17e2019-05-23 08:45:22 -07009782 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
9783 return NULL;
9784 }
9785
Larry Hastings2f936352014-08-05 14:04:04 +10009786 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009787 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009788#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009789 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009790 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009791 result = -1;
9792 else {
9793 result = _chsize_s(fd, length);
9794 close(fd);
9795 if (result < 0)
9796 errno = result;
9797 }
9798#else
9799 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009800#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009801 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009802 Py_END_ALLOW_THREADS
9803 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009804 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009805
9806 Py_RETURN_NONE;
9807}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009808#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009809
Ross Lagerwall7807c352011-03-17 20:20:30 +02009810
Victor Stinnerd6b17692014-09-30 12:20:05 +02009811/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9812 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9813 defined, which is the case in Python on AIX. AIX bug report:
9814 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9815#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9816# define POSIX_FADVISE_AIX_BUG
9817#endif
9818
Victor Stinnerec39e262014-09-30 12:35:58 +02009819
Victor Stinnerd6b17692014-09-30 12:20:05 +02009820#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009821/*[clinic input]
9822os.posix_fallocate
9823
9824 fd: int
9825 offset: Py_off_t
9826 length: Py_off_t
9827 /
9828
9829Ensure a file has allocated at least a particular number of bytes on disk.
9830
9831Ensure that the file specified by fd encompasses a range of bytes
9832starting at offset bytes from the beginning and continuing for length bytes.
9833[clinic start generated code]*/
9834
Larry Hastings2f936352014-08-05 14:04:04 +10009835static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009836os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009837 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009838/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009839{
9840 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009841 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009842
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009843 do {
9844 Py_BEGIN_ALLOW_THREADS
9845 result = posix_fallocate(fd, offset, length);
9846 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009847 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9848
9849 if (result == 0)
9850 Py_RETURN_NONE;
9851
9852 if (async_err)
9853 return NULL;
9854
9855 errno = result;
9856 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009857}
Victor Stinnerec39e262014-09-30 12:35:58 +02009858#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009859
Ross Lagerwall7807c352011-03-17 20:20:30 +02009860
Victor Stinnerd6b17692014-09-30 12:20:05 +02009861#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009862/*[clinic input]
9863os.posix_fadvise
9864
9865 fd: int
9866 offset: Py_off_t
9867 length: Py_off_t
9868 advice: int
9869 /
9870
9871Announce an intention to access data in a specific pattern.
9872
9873Announce an intention to access data in a specific pattern, thus allowing
9874the kernel to make optimizations.
9875The advice applies to the region of the file specified by fd starting at
9876offset and continuing for length bytes.
9877advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9878POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9879POSIX_FADV_DONTNEED.
9880[clinic start generated code]*/
9881
Larry Hastings2f936352014-08-05 14:04:04 +10009882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009883os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009884 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009885/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009886{
9887 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009888 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009889
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009890 do {
9891 Py_BEGIN_ALLOW_THREADS
9892 result = posix_fadvise(fd, offset, length, advice);
9893 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009894 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9895
9896 if (result == 0)
9897 Py_RETURN_NONE;
9898
9899 if (async_err)
9900 return NULL;
9901
9902 errno = result;
9903 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009904}
Victor Stinnerec39e262014-09-30 12:35:58 +02009905#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009906
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009907#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009908
Fred Drake762e2061999-08-26 17:23:54 +00009909/* Save putenv() parameters as values here, so we can collect them when they
9910 * get re-set with another call for the same key. */
9911static PyObject *posix_putenv_garbage;
9912
Larry Hastings2f936352014-08-05 14:04:04 +10009913static void
9914posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009915{
Larry Hastings2f936352014-08-05 14:04:04 +10009916 /* Install the first arg and newstr in posix_putenv_garbage;
9917 * this will cause previous value to be collected. This has to
9918 * happen after the real putenv() call because the old value
9919 * was still accessible until then. */
9920 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9921 /* really not much we can do; just leak */
9922 PyErr_Clear();
9923 else
9924 Py_DECREF(value);
9925}
9926
9927
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009928#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009929/*[clinic input]
9930os.putenv
9931
9932 name: unicode
9933 value: unicode
9934 /
9935
9936Change or add an environment variable.
9937[clinic start generated code]*/
9938
Larry Hastings2f936352014-08-05 14:04:04 +10009939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009940os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9941/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009942{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009943 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009944 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009945
Serhiy Storchaka77703942017-06-25 07:33:01 +03009946 /* Search from index 1 because on Windows starting '=' is allowed for
9947 defining hidden environment variables. */
9948 if (PyUnicode_GET_LENGTH(name) == 0 ||
9949 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9950 {
9951 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9952 return NULL;
9953 }
Larry Hastings2f936352014-08-05 14:04:04 +10009954 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9955 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009956 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009957 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009958
9959 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9960 if (env == NULL)
9961 goto error;
9962 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009963 PyErr_Format(PyExc_ValueError,
9964 "the environment variable is longer than %u characters",
9965 _MAX_ENV);
9966 goto error;
9967 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009968 if (wcslen(env) != (size_t)size) {
9969 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009970 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009971 }
9972
Larry Hastings2f936352014-08-05 14:04:04 +10009973 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009975 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009977
Larry Hastings2f936352014-08-05 14:04:04 +10009978 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009979 Py_RETURN_NONE;
9980
9981error:
Larry Hastings2f936352014-08-05 14:04:04 +10009982 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009983 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009984}
Larry Hastings2f936352014-08-05 14:04:04 +10009985#else /* MS_WINDOWS */
9986/*[clinic input]
9987os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009988
Larry Hastings2f936352014-08-05 14:04:04 +10009989 name: FSConverter
9990 value: FSConverter
9991 /
9992
9993Change or add an environment variable.
9994[clinic start generated code]*/
9995
Larry Hastings2f936352014-08-05 14:04:04 +10009996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009997os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9998/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009999{
10000 PyObject *bytes = NULL;
10001 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +030010002 const char *name_string = PyBytes_AS_STRING(name);
10003 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010004
Serhiy Storchaka77703942017-06-25 07:33:01 +030010005 if (strchr(name_string, '=') != NULL) {
10006 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10007 return NULL;
10008 }
Larry Hastings2f936352014-08-05 14:04:04 +100010009 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
10010 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010011 return NULL;
10012 }
10013
10014 env = PyBytes_AS_STRING(bytes);
10015 if (putenv(env)) {
10016 Py_DECREF(bytes);
10017 return posix_error();
10018 }
10019
10020 posix_putenv_garbage_setitem(name, bytes);
10021 Py_RETURN_NONE;
10022}
10023#endif /* MS_WINDOWS */
10024#endif /* HAVE_PUTENV */
10025
10026
10027#ifdef HAVE_UNSETENV
10028/*[clinic input]
10029os.unsetenv
10030 name: FSConverter
10031 /
10032
10033Delete an environment variable.
10034[clinic start generated code]*/
10035
Larry Hastings2f936352014-08-05 14:04:04 +100010036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010037os_unsetenv_impl(PyObject *module, PyObject *name)
10038/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010039{
Victor Stinner984890f2011-11-24 13:53:38 +010010040#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +010010041 int err;
Victor Stinner984890f2011-11-24 13:53:38 +010010042#endif
Victor Stinner84ae1182010-05-06 22:05:07 +000010043
Victor Stinner984890f2011-11-24 13:53:38 +010010044#ifdef HAVE_BROKEN_UNSETENV
10045 unsetenv(PyBytes_AS_STRING(name));
10046#else
Victor Stinner65170952011-11-22 22:16:17 +010010047 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +100010048 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +010010049 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +010010050#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010051
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 /* Remove the key from posix_putenv_garbage;
10053 * this will cause it to be collected. This has to
10054 * happen after the real unsetenv() call because the
10055 * old value was still accessible until then.
10056 */
Victor Stinner65170952011-11-22 22:16:17 +010010057 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020010059 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
10060 return NULL;
10061 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 PyErr_Clear();
10063 }
Victor Stinner84ae1182010-05-06 22:05:07 +000010064 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010065}
Larry Hastings2f936352014-08-05 14:04:04 +100010066#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +000010067
Larry Hastings2f936352014-08-05 14:04:04 +100010068
10069/*[clinic input]
10070os.strerror
10071
10072 code: int
10073 /
10074
10075Translate an error code to a message string.
10076[clinic start generated code]*/
10077
Larry Hastings2f936352014-08-05 14:04:04 +100010078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010079os_strerror_impl(PyObject *module, int code)
10080/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010081{
10082 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 if (message == NULL) {
10084 PyErr_SetString(PyExc_ValueError,
10085 "strerror() argument out of range");
10086 return NULL;
10087 }
Victor Stinner1b579672011-12-17 05:47:23 +010010088 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010089}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010090
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010091
Guido van Rossumc9641791998-08-04 15:26:23 +000010092#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010093#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010094/*[clinic input]
10095os.WCOREDUMP -> bool
10096
10097 status: int
10098 /
10099
10100Return True if the process returning status was dumped to a core file.
10101[clinic start generated code]*/
10102
Larry Hastings2f936352014-08-05 14:04:04 +100010103static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010104os_WCOREDUMP_impl(PyObject *module, int status)
10105/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010106{
10107 WAIT_TYPE wait_status;
10108 WAIT_STATUS_INT(wait_status) = status;
10109 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010110}
10111#endif /* WCOREDUMP */
10112
Larry Hastings2f936352014-08-05 14:04:04 +100010113
Fred Drake106c1a02002-04-23 15:58:02 +000010114#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010115/*[clinic input]
10116os.WIFCONTINUED -> bool
10117
10118 status: int
10119
10120Return True if a particular process was continued from a job control stop.
10121
10122Return True if the process returning status was continued from a
10123job control stop.
10124[clinic start generated code]*/
10125
Larry Hastings2f936352014-08-05 14:04:04 +100010126static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010127os_WIFCONTINUED_impl(PyObject *module, int status)
10128/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010129{
10130 WAIT_TYPE wait_status;
10131 WAIT_STATUS_INT(wait_status) = status;
10132 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010133}
10134#endif /* WIFCONTINUED */
10135
Larry Hastings2f936352014-08-05 14:04:04 +100010136
Guido van Rossumc9641791998-08-04 15:26:23 +000010137#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010138/*[clinic input]
10139os.WIFSTOPPED -> bool
10140
10141 status: int
10142
10143Return True if the process returning status was stopped.
10144[clinic start generated code]*/
10145
Larry Hastings2f936352014-08-05 14:04:04 +100010146static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010147os_WIFSTOPPED_impl(PyObject *module, int status)
10148/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010149{
10150 WAIT_TYPE wait_status;
10151 WAIT_STATUS_INT(wait_status) = status;
10152 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010153}
10154#endif /* WIFSTOPPED */
10155
Larry Hastings2f936352014-08-05 14:04:04 +100010156
Guido van Rossumc9641791998-08-04 15:26:23 +000010157#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010158/*[clinic input]
10159os.WIFSIGNALED -> bool
10160
10161 status: int
10162
10163Return True if the process returning status was terminated by a signal.
10164[clinic start generated code]*/
10165
Larry Hastings2f936352014-08-05 14:04:04 +100010166static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010167os_WIFSIGNALED_impl(PyObject *module, int status)
10168/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010169{
10170 WAIT_TYPE wait_status;
10171 WAIT_STATUS_INT(wait_status) = status;
10172 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010173}
10174#endif /* WIFSIGNALED */
10175
Larry Hastings2f936352014-08-05 14:04:04 +100010176
Guido van Rossumc9641791998-08-04 15:26:23 +000010177#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010178/*[clinic input]
10179os.WIFEXITED -> bool
10180
10181 status: int
10182
10183Return True if the process returning status exited via the exit() system call.
10184[clinic start generated code]*/
10185
Larry Hastings2f936352014-08-05 14:04:04 +100010186static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010187os_WIFEXITED_impl(PyObject *module, int status)
10188/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010189{
10190 WAIT_TYPE wait_status;
10191 WAIT_STATUS_INT(wait_status) = status;
10192 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010193}
10194#endif /* WIFEXITED */
10195
Larry Hastings2f936352014-08-05 14:04:04 +100010196
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010197#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010198/*[clinic input]
10199os.WEXITSTATUS -> int
10200
10201 status: int
10202
10203Return the process return code from status.
10204[clinic start generated code]*/
10205
Larry Hastings2f936352014-08-05 14:04:04 +100010206static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010207os_WEXITSTATUS_impl(PyObject *module, int status)
10208/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010209{
10210 WAIT_TYPE wait_status;
10211 WAIT_STATUS_INT(wait_status) = status;
10212 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010213}
10214#endif /* WEXITSTATUS */
10215
Larry Hastings2f936352014-08-05 14:04:04 +100010216
Guido van Rossumc9641791998-08-04 15:26:23 +000010217#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010218/*[clinic input]
10219os.WTERMSIG -> int
10220
10221 status: int
10222
10223Return the signal that terminated the process that provided the status value.
10224[clinic start generated code]*/
10225
Larry Hastings2f936352014-08-05 14:04:04 +100010226static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010227os_WTERMSIG_impl(PyObject *module, int status)
10228/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010229{
10230 WAIT_TYPE wait_status;
10231 WAIT_STATUS_INT(wait_status) = status;
10232 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010233}
10234#endif /* WTERMSIG */
10235
Larry Hastings2f936352014-08-05 14:04:04 +100010236
Guido van Rossumc9641791998-08-04 15:26:23 +000010237#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010238/*[clinic input]
10239os.WSTOPSIG -> int
10240
10241 status: int
10242
10243Return the signal that stopped the process that provided the status value.
10244[clinic start generated code]*/
10245
Larry Hastings2f936352014-08-05 14:04:04 +100010246static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010247os_WSTOPSIG_impl(PyObject *module, int status)
10248/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010249{
10250 WAIT_TYPE wait_status;
10251 WAIT_STATUS_INT(wait_status) = status;
10252 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010253}
10254#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010255#endif /* HAVE_SYS_WAIT_H */
10256
10257
Thomas Wouters477c8d52006-05-27 19:21:47 +000010258#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010259#ifdef _SCO_DS
10260/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10261 needed definitions in sys/statvfs.h */
10262#define _SVID3
10263#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010264#include <sys/statvfs.h>
10265
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010266static PyObject*
10267_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010268 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 if (v == NULL)
10270 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010271
10272#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10274 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10275 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10276 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10277 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10278 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10279 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10280 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10281 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10282 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010283#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10285 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10286 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010287 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010289 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010291 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010293 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010295 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010297 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10299 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010300#endif
Michael Felt502d5512018-01-05 13:01:58 +010010301/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10302 * (issue #32390). */
10303#if defined(_AIX) && defined(_ALL_SOURCE)
10304 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10305#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010306 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010307#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010308 if (PyErr_Occurred()) {
10309 Py_DECREF(v);
10310 return NULL;
10311 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010312
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010314}
10315
Larry Hastings2f936352014-08-05 14:04:04 +100010316
10317/*[clinic input]
10318os.fstatvfs
10319 fd: int
10320 /
10321
10322Perform an fstatvfs system call on the given fd.
10323
10324Equivalent to statvfs(fd).
10325[clinic start generated code]*/
10326
Larry Hastings2f936352014-08-05 14:04:04 +100010327static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010328os_fstatvfs_impl(PyObject *module, int fd)
10329/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010330{
10331 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010332 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010334
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010335 do {
10336 Py_BEGIN_ALLOW_THREADS
10337 result = fstatvfs(fd, &st);
10338 Py_END_ALLOW_THREADS
10339 } while (result != 0 && errno == EINTR &&
10340 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010341 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010342 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010343
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010345}
Larry Hastings2f936352014-08-05 14:04:04 +100010346#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010347
10348
Thomas Wouters477c8d52006-05-27 19:21:47 +000010349#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010350#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010351/*[clinic input]
10352os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010353
Larry Hastings2f936352014-08-05 14:04:04 +100010354 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10355
10356Perform a statvfs system call on the given path.
10357
10358path may always be specified as a string.
10359On some platforms, path may also be specified as an open file descriptor.
10360 If this functionality is unavailable, using it raises an exception.
10361[clinic start generated code]*/
10362
Larry Hastings2f936352014-08-05 14:04:04 +100010363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010364os_statvfs_impl(PyObject *module, path_t *path)
10365/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010366{
10367 int result;
10368 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010369
10370 Py_BEGIN_ALLOW_THREADS
10371#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010372 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010373#ifdef __APPLE__
10374 /* handle weak-linking on Mac OS X 10.3 */
10375 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010376 fd_specified("statvfs", path->fd);
10377 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010378 }
10379#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010380 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010381 }
10382 else
10383#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010384 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010385 Py_END_ALLOW_THREADS
10386
10387 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010388 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010389 }
10390
Larry Hastings2f936352014-08-05 14:04:04 +100010391 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010392}
Larry Hastings2f936352014-08-05 14:04:04 +100010393#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10394
Guido van Rossum94f6f721999-01-06 18:42:14 +000010395
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010396#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010397/*[clinic input]
10398os._getdiskusage
10399
Steve Dower23ad6d02018-02-22 10:39:10 -080010400 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010401
10402Return disk usage statistics about the given path as a (total, free) tuple.
10403[clinic start generated code]*/
10404
Larry Hastings2f936352014-08-05 14:04:04 +100010405static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010406os__getdiskusage_impl(PyObject *module, path_t *path)
10407/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010408{
10409 BOOL retval;
10410 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010411 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010412
10413 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010414 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010415 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010416 if (retval == 0) {
10417 if (GetLastError() == ERROR_DIRECTORY) {
10418 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010419
Joe Pamerc8c02492018-09-25 10:57:36 -040010420 dir_path = PyMem_New(wchar_t, path->length + 1);
10421 if (dir_path == NULL) {
10422 return PyErr_NoMemory();
10423 }
10424
10425 wcscpy_s(dir_path, path->length + 1, path->wide);
10426
10427 if (_dirnameW(dir_path) != -1) {
10428 Py_BEGIN_ALLOW_THREADS
10429 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10430 Py_END_ALLOW_THREADS
10431 }
10432 /* Record the last error in case it's modified by PyMem_Free. */
10433 err = GetLastError();
10434 PyMem_Free(dir_path);
10435 if (retval) {
10436 goto success;
10437 }
10438 }
10439 return PyErr_SetFromWindowsErr(err);
10440 }
10441
10442success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010443 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10444}
Larry Hastings2f936352014-08-05 14:04:04 +100010445#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010446
10447
Fred Drakec9680921999-12-13 16:37:25 +000010448/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10449 * It maps strings representing configuration variable names to
10450 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010451 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010452 * rarely-used constants. There are three separate tables that use
10453 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010454 *
10455 * This code is always included, even if none of the interfaces that
10456 * need it are included. The #if hackery needed to avoid it would be
10457 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010458 */
10459struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010460 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010461 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010462};
10463
Fred Drake12c6e2d1999-12-14 21:25:03 +000010464static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010465conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010466 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010467{
Christian Heimes217cfd12007-12-02 14:31:20 +000010468 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010469 int value = _PyLong_AsInt(arg);
10470 if (value == -1 && PyErr_Occurred())
10471 return 0;
10472 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010473 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010474 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010475 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010476 /* look up the value in the table using a binary search */
10477 size_t lo = 0;
10478 size_t mid;
10479 size_t hi = tablesize;
10480 int cmp;
10481 const char *confname;
10482 if (!PyUnicode_Check(arg)) {
10483 PyErr_SetString(PyExc_TypeError,
10484 "configuration names must be strings or integers");
10485 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010487 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010488 if (confname == NULL)
10489 return 0;
10490 while (lo < hi) {
10491 mid = (lo + hi) / 2;
10492 cmp = strcmp(confname, table[mid].name);
10493 if (cmp < 0)
10494 hi = mid;
10495 else if (cmp > 0)
10496 lo = mid + 1;
10497 else {
10498 *valuep = table[mid].value;
10499 return 1;
10500 }
10501 }
10502 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10503 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010505}
10506
10507
10508#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10509static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010510#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010512#endif
10513#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010515#endif
Fred Drakec9680921999-12-13 16:37:25 +000010516#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010561#ifdef _PC_ACL_ENABLED
10562 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10563#endif
10564#ifdef _PC_MIN_HOLE_SIZE
10565 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10566#endif
10567#ifdef _PC_ALLOC_SIZE_MIN
10568 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10569#endif
10570#ifdef _PC_REC_INCR_XFER_SIZE
10571 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10572#endif
10573#ifdef _PC_REC_MAX_XFER_SIZE
10574 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10575#endif
10576#ifdef _PC_REC_MIN_XFER_SIZE
10577 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10578#endif
10579#ifdef _PC_REC_XFER_ALIGN
10580 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10581#endif
10582#ifdef _PC_SYMLINK_MAX
10583 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10584#endif
10585#ifdef _PC_XATTR_ENABLED
10586 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10587#endif
10588#ifdef _PC_XATTR_EXISTS
10589 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10590#endif
10591#ifdef _PC_TIMESTAMP_RESOLUTION
10592 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10593#endif
Fred Drakec9680921999-12-13 16:37:25 +000010594};
10595
Fred Drakec9680921999-12-13 16:37:25 +000010596static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010597conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010598{
10599 return conv_confname(arg, valuep, posix_constants_pathconf,
10600 sizeof(posix_constants_pathconf)
10601 / sizeof(struct constdef));
10602}
10603#endif
10604
Larry Hastings2f936352014-08-05 14:04:04 +100010605
Fred Drakec9680921999-12-13 16:37:25 +000010606#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010607/*[clinic input]
10608os.fpathconf -> long
10609
10610 fd: int
10611 name: path_confname
10612 /
10613
10614Return the configuration limit name for the file descriptor fd.
10615
10616If there is no limit, return -1.
10617[clinic start generated code]*/
10618
Larry Hastings2f936352014-08-05 14:04:04 +100010619static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010620os_fpathconf_impl(PyObject *module, int fd, int name)
10621/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010622{
10623 long limit;
10624
10625 errno = 0;
10626 limit = fpathconf(fd, name);
10627 if (limit == -1 && errno != 0)
10628 posix_error();
10629
10630 return limit;
10631}
10632#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010633
10634
10635#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010636/*[clinic input]
10637os.pathconf -> long
10638 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10639 name: path_confname
10640
10641Return the configuration limit name for the file or directory path.
10642
10643If there is no limit, return -1.
10644On some platforms, path may also be specified as an open file descriptor.
10645 If this functionality is unavailable, using it raises an exception.
10646[clinic start generated code]*/
10647
Larry Hastings2f936352014-08-05 14:04:04 +100010648static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010649os_pathconf_impl(PyObject *module, path_t *path, int name)
10650/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010651{
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010653
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010655#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010656 if (path->fd != -1)
10657 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010658 else
10659#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010660 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010661 if (limit == -1 && errno != 0) {
10662 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010663 /* could be a path or name problem */
10664 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010665 else
Larry Hastings2f936352014-08-05 14:04:04 +100010666 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 }
Larry Hastings2f936352014-08-05 14:04:04 +100010668
10669 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010670}
Larry Hastings2f936352014-08-05 14:04:04 +100010671#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010672
10673#ifdef HAVE_CONFSTR
10674static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010675#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010677#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010678#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010680#endif
10681#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010683#endif
Fred Draked86ed291999-12-15 15:34:33 +000010684#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010686#endif
10687#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010689#endif
10690#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010692#endif
10693#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010695#endif
Fred Drakec9680921999-12-13 16:37:25 +000010696#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010698#endif
10699#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010701#endif
10702#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010704#endif
10705#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010707#endif
10708#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010710#endif
10711#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010713#endif
10714#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010716#endif
10717#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010719#endif
Fred Draked86ed291999-12-15 15:34:33 +000010720#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010722#endif
Fred Drakec9680921999-12-13 16:37:25 +000010723#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010725#endif
Fred Draked86ed291999-12-15 15:34:33 +000010726#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010728#endif
10729#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010731#endif
10732#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010734#endif
10735#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010737#endif
Fred Drakec9680921999-12-13 16:37:25 +000010738#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010740#endif
10741#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010743#endif
10744#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010746#endif
10747#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010749#endif
10750#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010752#endif
10753#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010755#endif
10756#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010758#endif
10759#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010761#endif
10762#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010764#endif
10765#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010767#endif
10768#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010770#endif
10771#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010773#endif
10774#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010776#endif
10777#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010779#endif
10780#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010782#endif
10783#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010785#endif
Fred Draked86ed291999-12-15 15:34:33 +000010786#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010788#endif
10789#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010791#endif
10792#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010794#endif
10795#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010797#endif
10798#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010800#endif
10801#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010803#endif
10804#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010806#endif
10807#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010809#endif
10810#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010812#endif
10813#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010815#endif
10816#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010818#endif
10819#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010821#endif
10822#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010824#endif
Fred Drakec9680921999-12-13 16:37:25 +000010825};
10826
10827static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010828conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010829{
10830 return conv_confname(arg, valuep, posix_constants_confstr,
10831 sizeof(posix_constants_confstr)
10832 / sizeof(struct constdef));
10833}
10834
Larry Hastings2f936352014-08-05 14:04:04 +100010835
10836/*[clinic input]
10837os.confstr
10838
10839 name: confstr_confname
10840 /
10841
10842Return a string-valued system configuration variable.
10843[clinic start generated code]*/
10844
Larry Hastings2f936352014-08-05 14:04:04 +100010845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010846os_confstr_impl(PyObject *module, int name)
10847/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010848{
10849 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010850 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010851 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010852
Victor Stinnercb043522010-09-10 23:49:04 +000010853 errno = 0;
10854 len = confstr(name, buffer, sizeof(buffer));
10855 if (len == 0) {
10856 if (errno) {
10857 posix_error();
10858 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010859 }
10860 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010861 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010862 }
10863 }
Victor Stinnercb043522010-09-10 23:49:04 +000010864
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010865 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010866 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010867 char *buf = PyMem_Malloc(len);
10868 if (buf == NULL)
10869 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010870 len2 = confstr(name, buf, len);
10871 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010872 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010873 PyMem_Free(buf);
10874 }
10875 else
10876 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010877 return result;
10878}
Larry Hastings2f936352014-08-05 14:04:04 +100010879#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010880
10881
10882#ifdef HAVE_SYSCONF
10883static struct constdef posix_constants_sysconf[] = {
10884#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010886#endif
10887#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
10890#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
10893#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
10908#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010910#endif
10911#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010913#endif
Fred Draked86ed291999-12-15 15:34:33 +000010914#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010916#endif
10917#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010919#endif
Fred Drakec9680921999-12-13 16:37:25 +000010920#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010922#endif
Fred Drakec9680921999-12-13 16:37:25 +000010923#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010925#endif
10926#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010928#endif
10929#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010931#endif
10932#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010934#endif
10935#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
Fred Draked86ed291999-12-15 15:34:33 +000010938#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010940#endif
Fred Drakec9680921999-12-13 16:37:25 +000010941#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010943#endif
10944#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010946#endif
10947#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010949#endif
10950#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010952#endif
10953#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010955#endif
Fred Draked86ed291999-12-15 15:34:33 +000010956#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010958#endif
Fred Drakec9680921999-12-13 16:37:25 +000010959#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010961#endif
10962#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010964#endif
10965#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
10968#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010970#endif
10971#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010973#endif
10974#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010976#endif
10977#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010979#endif
10980#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010982#endif
10983#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010985#endif
10986#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010988#endif
10989#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010991#endif
10992#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010994#endif
10995#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010997#endif
10998#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011000#endif
11001#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011003#endif
11004#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011006#endif
11007#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011009#endif
11010#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011012#endif
11013#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011015#endif
11016#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011018#endif
11019#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011021#endif
11022#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011024#endif
11025#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011027#endif
Fred Draked86ed291999-12-15 15:34:33 +000011028#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011030#endif
Fred Drakec9680921999-12-13 16:37:25 +000011031#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011033#endif
11034#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011036#endif
11037#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011039#endif
Fred Draked86ed291999-12-15 15:34:33 +000011040#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011042#endif
Fred Drakec9680921999-12-13 16:37:25 +000011043#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011045#endif
Fred Draked86ed291999-12-15 15:34:33 +000011046#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011048#endif
11049#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011051#endif
Fred Drakec9680921999-12-13 16:37:25 +000011052#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011054#endif
11055#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011057#endif
11058#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011060#endif
11061#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011063#endif
Fred Draked86ed291999-12-15 15:34:33 +000011064#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011066#endif
Fred Drakec9680921999-12-13 16:37:25 +000011067#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011069#endif
11070#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011072#endif
11073#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011075#endif
11076#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011078#endif
11079#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011081#endif
11082#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011084#endif
11085#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011087#endif
Fred Draked86ed291999-12-15 15:34:33 +000011088#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011090#endif
Fred Drakec9680921999-12-13 16:37:25 +000011091#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011093#endif
11094#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011096#endif
Fred Draked86ed291999-12-15 15:34:33 +000011097#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011099#endif
Fred Drakec9680921999-12-13 16:37:25 +000011100#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011102#endif
11103#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
11106#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
11121#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
11124#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011126#endif
Fred Draked86ed291999-12-15 15:34:33 +000011127#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011129#endif
11130#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011132#endif
Fred Drakec9680921999-12-13 16:37:25 +000011133#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011135#endif
11136#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011138#endif
11139#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011141#endif
11142#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011144#endif
11145#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011147#endif
11148#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011150#endif
11151#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011153#endif
11154#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011156#endif
11157#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011159#endif
11160#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011162#endif
11163#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011165#endif
11166#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011168#endif
11169#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011171#endif
11172#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011174#endif
11175#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011177#endif
11178#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011180#endif
11181#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011183#endif
11184#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011186#endif
11187#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011189#endif
11190#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011192#endif
11193#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011194 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011195#endif
11196#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011197 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011198#endif
11199#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011200 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011201#endif
11202#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011204#endif
11205#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011207#endif
11208#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011210#endif
11211#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011213#endif
11214#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011216#endif
11217#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011219#endif
11220#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011222#endif
11223#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011225#endif
11226#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011228#endif
11229#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011231#endif
11232#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011234#endif
11235#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011237#endif
Fred Draked86ed291999-12-15 15:34:33 +000011238#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011240#endif
Fred Drakec9680921999-12-13 16:37:25 +000011241#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011243#endif
11244#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011246#endif
11247#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011249#endif
11250#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011252#endif
11253#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011255#endif
11256#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011258#endif
11259#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011261#endif
11262#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011263 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011264#endif
11265#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011267#endif
11268#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011270#endif
11271#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011272 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011273#endif
11274#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011275 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011276#endif
11277#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011279#endif
11280#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011281 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011282#endif
11283#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011285#endif
11286#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011287 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011288#endif
11289#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011291#endif
11292#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011294#endif
11295#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011297#endif
11298#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011300#endif
11301#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011303#endif
11304#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011306#endif
11307#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011308 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011309#endif
11310#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011312#endif
11313#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011315#endif
11316#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011317 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011318#endif
11319#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011320 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011321#endif
11322#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011324#endif
11325#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011327#endif
11328#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011330#endif
11331#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011333#endif
11334#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011336#endif
11337#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011339#endif
11340#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011342#endif
11343#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011345#endif
11346#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011348#endif
11349#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011351#endif
11352#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011354#endif
11355#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011357#endif
11358#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011360#endif
11361#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011363#endif
11364#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011366#endif
11367#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011369#endif
11370#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011372#endif
11373#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011374 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011375#endif
11376};
11377
11378static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011379conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011380{
11381 return conv_confname(arg, valuep, posix_constants_sysconf,
11382 sizeof(posix_constants_sysconf)
11383 / sizeof(struct constdef));
11384}
11385
Larry Hastings2f936352014-08-05 14:04:04 +100011386
11387/*[clinic input]
11388os.sysconf -> long
11389 name: sysconf_confname
11390 /
11391
11392Return an integer-valued system configuration variable.
11393[clinic start generated code]*/
11394
Larry Hastings2f936352014-08-05 14:04:04 +100011395static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011396os_sysconf_impl(PyObject *module, int name)
11397/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011398{
11399 long value;
11400
11401 errno = 0;
11402 value = sysconf(name);
11403 if (value == -1 && errno != 0)
11404 posix_error();
11405 return value;
11406}
11407#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011408
11409
Fred Drakebec628d1999-12-15 18:31:10 +000011410/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011411 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011412 * the exported dictionaries that are used to publish information about the
11413 * names available on the host platform.
11414 *
11415 * Sorting the table at runtime ensures that the table is properly ordered
11416 * when used, even for platforms we're not able to test on. It also makes
11417 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011418 */
Fred Drakebec628d1999-12-15 18:31:10 +000011419
11420static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011421cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011422{
11423 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011425 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011427
11428 return strcmp(c1->name, c2->name);
11429}
11430
11431static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011432setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011433 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011434{
Fred Drakebec628d1999-12-15 18:31:10 +000011435 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011436 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011437
11438 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11439 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011440 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011442
Barry Warsaw3155db32000-04-13 15:20:40 +000011443 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 PyObject *o = PyLong_FromLong(table[i].value);
11445 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11446 Py_XDECREF(o);
11447 Py_DECREF(d);
11448 return -1;
11449 }
11450 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011451 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011452 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011453}
11454
Fred Drakebec628d1999-12-15 18:31:10 +000011455/* Return -1 on failure, 0 on success. */
11456static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011457setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011458{
11459#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011460 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011461 sizeof(posix_constants_pathconf)
11462 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011463 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011464 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011465#endif
11466#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011467 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011468 sizeof(posix_constants_confstr)
11469 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011470 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011471 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011472#endif
11473#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011474 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011475 sizeof(posix_constants_sysconf)
11476 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011477 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011478 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011479#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011480 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011481}
Fred Draked86ed291999-12-15 15:34:33 +000011482
11483
Larry Hastings2f936352014-08-05 14:04:04 +100011484/*[clinic input]
11485os.abort
11486
11487Abort the interpreter immediately.
11488
11489This function 'dumps core' or otherwise fails in the hardest way possible
11490on the hosting operating system. This function never returns.
11491[clinic start generated code]*/
11492
Larry Hastings2f936352014-08-05 14:04:04 +100011493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011494os_abort_impl(PyObject *module)
11495/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011496{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011497 abort();
11498 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011499#ifndef __clang__
11500 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11501 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11502 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011503 Py_FatalError("abort() called from Python code didn't abort!");
11504 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011505#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011506}
Fred Drakebec628d1999-12-15 18:31:10 +000011507
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011508#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011509/* Grab ShellExecute dynamically from shell32 */
11510static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011511static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11512 LPCWSTR, INT);
11513static int
11514check_ShellExecute()
11515{
11516 HINSTANCE hShell32;
11517
11518 /* only recheck */
11519 if (-1 == has_ShellExecute) {
11520 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011521 /* Security note: this call is not vulnerable to "DLL hijacking".
11522 SHELL32 is part of "KnownDLLs" and so Windows always load
11523 the system SHELL32.DLL, even if there is another SHELL32.DLL
11524 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011525 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011526 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011527 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11528 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011529 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011530 } else {
11531 has_ShellExecute = 0;
11532 }
Tony Roberts4860f012019-02-02 18:16:42 +010011533 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011534 }
11535 return has_ShellExecute;
11536}
11537
11538
Steve Dowercc16be82016-09-08 10:35:16 -070011539/*[clinic input]
11540os.startfile
11541 filepath: path_t
11542 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011543
Steve Dowercc16be82016-09-08 10:35:16 -070011544startfile(filepath [, operation])
11545
11546Start a file with its associated application.
11547
11548When "operation" is not specified or "open", this acts like
11549double-clicking the file in Explorer, or giving the file name as an
11550argument to the DOS "start" command: the file is opened with whatever
11551application (if any) its extension is associated.
11552When another "operation" is given, it specifies what should be done with
11553the file. A typical operation is "print".
11554
11555startfile returns as soon as the associated application is launched.
11556There is no option to wait for the application to close, and no way
11557to retrieve the application's exit status.
11558
11559The filepath is relative to the current directory. If you want to use
11560an absolute path, make sure the first character is not a slash ("/");
11561the underlying Win32 ShellExecute function doesn't work if it is.
11562[clinic start generated code]*/
11563
11564static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011565os_startfile_impl(PyObject *module, path_t *filepath,
11566 const Py_UNICODE *operation)
11567/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011568{
11569 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011570
11571 if(!check_ShellExecute()) {
11572 /* If the OS doesn't have ShellExecute, return a
11573 NotImplementedError. */
11574 return PyErr_Format(PyExc_NotImplementedError,
11575 "startfile not available on this platform");
11576 }
11577
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011579 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011580 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011581 Py_END_ALLOW_THREADS
11582
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011584 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011585 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 }
Steve Dowercc16be82016-09-08 10:35:16 -070011587 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011588}
Larry Hastings2f936352014-08-05 14:04:04 +100011589#endif /* MS_WINDOWS */
11590
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011591
Martin v. Löwis438b5342002-12-27 10:16:42 +000011592#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011593/*[clinic input]
11594os.getloadavg
11595
11596Return average recent system load information.
11597
11598Return the number of processes in the system run queue averaged over
11599the last 1, 5, and 15 minutes as a tuple of three floats.
11600Raises OSError if the load average was unobtainable.
11601[clinic start generated code]*/
11602
Larry Hastings2f936352014-08-05 14:04:04 +100011603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011604os_getloadavg_impl(PyObject *module)
11605/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011606{
11607 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011608 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011609 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11610 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011611 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011612 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011613}
Larry Hastings2f936352014-08-05 14:04:04 +100011614#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011615
Larry Hastings2f936352014-08-05 14:04:04 +100011616
11617/*[clinic input]
11618os.device_encoding
11619 fd: int
11620
11621Return a string describing the encoding of a terminal's file descriptor.
11622
11623The file descriptor must be attached to a terminal.
11624If the device is not a terminal, return None.
11625[clinic start generated code]*/
11626
Larry Hastings2f936352014-08-05 14:04:04 +100011627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011628os_device_encoding_impl(PyObject *module, int fd)
11629/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011630{
Brett Cannonefb00c02012-02-29 18:31:31 -050011631 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011632}
11633
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011634
Larry Hastings2f936352014-08-05 14:04:04 +100011635#ifdef HAVE_SETRESUID
11636/*[clinic input]
11637os.setresuid
11638
11639 ruid: uid_t
11640 euid: uid_t
11641 suid: uid_t
11642 /
11643
11644Set the current process's real, effective, and saved user ids.
11645[clinic start generated code]*/
11646
Larry Hastings2f936352014-08-05 14:04:04 +100011647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011648os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11649/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011650{
Victor Stinner8c62be82010-05-06 00:08:46 +000011651 if (setresuid(ruid, euid, suid) < 0)
11652 return posix_error();
11653 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011654}
Larry Hastings2f936352014-08-05 14:04:04 +100011655#endif /* HAVE_SETRESUID */
11656
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011657
11658#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011659/*[clinic input]
11660os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011661
Larry Hastings2f936352014-08-05 14:04:04 +100011662 rgid: gid_t
11663 egid: gid_t
11664 sgid: gid_t
11665 /
11666
11667Set the current process's real, effective, and saved group ids.
11668[clinic start generated code]*/
11669
Larry Hastings2f936352014-08-05 14:04:04 +100011670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011671os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11672/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011673{
Victor Stinner8c62be82010-05-06 00:08:46 +000011674 if (setresgid(rgid, egid, sgid) < 0)
11675 return posix_error();
11676 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011677}
Larry Hastings2f936352014-08-05 14:04:04 +100011678#endif /* HAVE_SETRESGID */
11679
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011680
11681#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011682/*[clinic input]
11683os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011684
Larry Hastings2f936352014-08-05 14:04:04 +100011685Return a tuple of the current process's real, effective, and saved user ids.
11686[clinic start generated code]*/
11687
Larry Hastings2f936352014-08-05 14:04:04 +100011688static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011689os_getresuid_impl(PyObject *module)
11690/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011691{
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011693 if (getresuid(&ruid, &euid, &suid) < 0)
11694 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011695 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11696 _PyLong_FromUid(euid),
11697 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011698}
Larry Hastings2f936352014-08-05 14:04:04 +100011699#endif /* HAVE_GETRESUID */
11700
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011701
11702#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011703/*[clinic input]
11704os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011705
Larry Hastings2f936352014-08-05 14:04:04 +100011706Return a tuple of the current process's real, effective, and saved group ids.
11707[clinic start generated code]*/
11708
Larry Hastings2f936352014-08-05 14:04:04 +100011709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011710os_getresgid_impl(PyObject *module)
11711/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011712{
11713 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011714 if (getresgid(&rgid, &egid, &sgid) < 0)
11715 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011716 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11717 _PyLong_FromGid(egid),
11718 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011719}
Larry Hastings2f936352014-08-05 14:04:04 +100011720#endif /* HAVE_GETRESGID */
11721
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011722
Benjamin Peterson9428d532011-09-14 11:45:52 -040011723#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011724/*[clinic input]
11725os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011726
Larry Hastings2f936352014-08-05 14:04:04 +100011727 path: path_t(allow_fd=True)
11728 attribute: path_t
11729 *
11730 follow_symlinks: bool = True
11731
11732Return the value of extended attribute attribute on path.
11733
BNMetricsb9427072018-11-02 15:20:19 +000011734path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011735If follow_symlinks is False, and the last element of the path is a symbolic
11736 link, getxattr will examine the symbolic link itself instead of the file
11737 the link points to.
11738
11739[clinic start generated code]*/
11740
Larry Hastings2f936352014-08-05 14:04:04 +100011741static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011742os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011743 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011744/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011745{
11746 Py_ssize_t i;
11747 PyObject *buffer = NULL;
11748
11749 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11750 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011751
Larry Hastings9cf065c2012-06-22 16:30:09 -070011752 for (i = 0; ; i++) {
11753 void *ptr;
11754 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011755 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011756 Py_ssize_t buffer_size = buffer_sizes[i];
11757 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011758 path_error(path);
11759 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011760 }
11761 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11762 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011763 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011764 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011765
Larry Hastings9cf065c2012-06-22 16:30:09 -070011766 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011767 if (path->fd >= 0)
11768 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011769 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011770 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011771 else
Larry Hastings2f936352014-08-05 14:04:04 +100011772 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011773 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011774
Larry Hastings9cf065c2012-06-22 16:30:09 -070011775 if (result < 0) {
11776 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011777 if (errno == ERANGE)
11778 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011779 path_error(path);
11780 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011781 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011782
Larry Hastings9cf065c2012-06-22 16:30:09 -070011783 if (result != buffer_size) {
11784 /* Can only shrink. */
11785 _PyBytes_Resize(&buffer, result);
11786 }
11787 break;
11788 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011789
Larry Hastings9cf065c2012-06-22 16:30:09 -070011790 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011791}
11792
Larry Hastings2f936352014-08-05 14:04:04 +100011793
11794/*[clinic input]
11795os.setxattr
11796
11797 path: path_t(allow_fd=True)
11798 attribute: path_t
11799 value: Py_buffer
11800 flags: int = 0
11801 *
11802 follow_symlinks: bool = True
11803
11804Set extended attribute attribute on path to value.
11805
BNMetricsb9427072018-11-02 15:20:19 +000011806path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011807If follow_symlinks is False, and the last element of the path is a symbolic
11808 link, setxattr will modify the symbolic link itself instead of the file
11809 the link points to.
11810
11811[clinic start generated code]*/
11812
Benjamin Peterson799bd802011-08-31 22:15:17 -040011813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011814os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011815 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011816/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011817{
Larry Hastings2f936352014-08-05 14:04:04 +100011818 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011819
Larry Hastings2f936352014-08-05 14:04:04 +100011820 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011821 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011822
Benjamin Peterson799bd802011-08-31 22:15:17 -040011823 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011824 if (path->fd > -1)
11825 result = fsetxattr(path->fd, attribute->narrow,
11826 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011827 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011828 result = setxattr(path->narrow, attribute->narrow,
11829 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011830 else
Larry Hastings2f936352014-08-05 14:04:04 +100011831 result = lsetxattr(path->narrow, attribute->narrow,
11832 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011833 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011834
Larry Hastings9cf065c2012-06-22 16:30:09 -070011835 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011836 path_error(path);
11837 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011838 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011839
Larry Hastings2f936352014-08-05 14:04:04 +100011840 Py_RETURN_NONE;
11841}
11842
11843
11844/*[clinic input]
11845os.removexattr
11846
11847 path: path_t(allow_fd=True)
11848 attribute: path_t
11849 *
11850 follow_symlinks: bool = True
11851
11852Remove extended attribute attribute on path.
11853
BNMetricsb9427072018-11-02 15:20:19 +000011854path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011855If follow_symlinks is False, and the last element of the path is a symbolic
11856 link, removexattr will modify the symbolic link itself instead of the file
11857 the link points to.
11858
11859[clinic start generated code]*/
11860
Larry Hastings2f936352014-08-05 14:04:04 +100011861static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011862os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011863 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011864/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011865{
11866 ssize_t result;
11867
11868 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11869 return NULL;
11870
11871 Py_BEGIN_ALLOW_THREADS;
11872 if (path->fd > -1)
11873 result = fremovexattr(path->fd, attribute->narrow);
11874 else if (follow_symlinks)
11875 result = removexattr(path->narrow, attribute->narrow);
11876 else
11877 result = lremovexattr(path->narrow, attribute->narrow);
11878 Py_END_ALLOW_THREADS;
11879
11880 if (result) {
11881 return path_error(path);
11882 }
11883
11884 Py_RETURN_NONE;
11885}
11886
11887
11888/*[clinic input]
11889os.listxattr
11890
11891 path: path_t(allow_fd=True, nullable=True) = None
11892 *
11893 follow_symlinks: bool = True
11894
11895Return a list of extended attributes on path.
11896
BNMetricsb9427072018-11-02 15:20:19 +000011897path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011898if path is None, listxattr will examine the current directory.
11899If follow_symlinks is False, and the last element of the path is a symbolic
11900 link, listxattr will examine the symbolic link itself instead of the file
11901 the link points to.
11902[clinic start generated code]*/
11903
Larry Hastings2f936352014-08-05 14:04:04 +100011904static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011905os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011906/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011907{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011908 Py_ssize_t i;
11909 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011910 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011911 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011912
Larry Hastings2f936352014-08-05 14:04:04 +100011913 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011914 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011915
Larry Hastings2f936352014-08-05 14:04:04 +100011916 name = path->narrow ? path->narrow : ".";
11917
Larry Hastings9cf065c2012-06-22 16:30:09 -070011918 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011919 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011920 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011921 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011922 Py_ssize_t buffer_size = buffer_sizes[i];
11923 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011924 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011925 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011926 break;
11927 }
11928 buffer = PyMem_MALLOC(buffer_size);
11929 if (!buffer) {
11930 PyErr_NoMemory();
11931 break;
11932 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011933
Larry Hastings9cf065c2012-06-22 16:30:09 -070011934 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011935 if (path->fd > -1)
11936 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011937 else if (follow_symlinks)
11938 length = listxattr(name, buffer, buffer_size);
11939 else
11940 length = llistxattr(name, buffer, buffer_size);
11941 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011942
Larry Hastings9cf065c2012-06-22 16:30:09 -070011943 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011944 if (errno == ERANGE) {
11945 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011946 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011947 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011948 }
Larry Hastings2f936352014-08-05 14:04:04 +100011949 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011950 break;
11951 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011952
Larry Hastings9cf065c2012-06-22 16:30:09 -070011953 result = PyList_New(0);
11954 if (!result) {
11955 goto exit;
11956 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011957
Larry Hastings9cf065c2012-06-22 16:30:09 -070011958 end = buffer + length;
11959 for (trace = start = buffer; trace != end; trace++) {
11960 if (!*trace) {
11961 int error;
11962 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11963 trace - start);
11964 if (!attribute) {
11965 Py_DECREF(result);
11966 result = NULL;
11967 goto exit;
11968 }
11969 error = PyList_Append(result, attribute);
11970 Py_DECREF(attribute);
11971 if (error) {
11972 Py_DECREF(result);
11973 result = NULL;
11974 goto exit;
11975 }
11976 start = trace + 1;
11977 }
11978 }
11979 break;
11980 }
11981exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011982 if (buffer)
11983 PyMem_FREE(buffer);
11984 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011985}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011986#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011987
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011988
Larry Hastings2f936352014-08-05 14:04:04 +100011989/*[clinic input]
11990os.urandom
11991
11992 size: Py_ssize_t
11993 /
11994
11995Return a bytes object containing random bytes suitable for cryptographic use.
11996[clinic start generated code]*/
11997
Larry Hastings2f936352014-08-05 14:04:04 +100011998static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011999os_urandom_impl(PyObject *module, Py_ssize_t size)
12000/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012001{
12002 PyObject *bytes;
12003 int result;
12004
Georg Brandl2fb477c2012-02-21 00:33:36 +010012005 if (size < 0)
12006 return PyErr_Format(PyExc_ValueError,
12007 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012008 bytes = PyBytes_FromStringAndSize(NULL, size);
12009 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012010 return NULL;
12011
Victor Stinnere66987e2016-09-06 16:33:52 -070012012 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012013 if (result == -1) {
12014 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012015 return NULL;
12016 }
Larry Hastings2f936352014-08-05 14:04:04 +100012017 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012018}
12019
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012020#ifdef HAVE_MEMFD_CREATE
12021/*[clinic input]
12022os.memfd_create
12023
12024 name: FSConverter
12025 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12026
12027[clinic start generated code]*/
12028
12029static PyObject *
12030os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12031/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12032{
12033 int fd;
12034 const char *bytes = PyBytes_AS_STRING(name);
12035 Py_BEGIN_ALLOW_THREADS
12036 fd = memfd_create(bytes, flags);
12037 Py_END_ALLOW_THREADS
12038 if (fd == -1) {
12039 return PyErr_SetFromErrno(PyExc_OSError);
12040 }
12041 return PyLong_FromLong(fd);
12042}
12043#endif
12044
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012045/* Terminal size querying */
12046
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012047static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012048
12049PyDoc_STRVAR(TerminalSize_docstring,
12050 "A tuple of (columns, lines) for holding terminal window size");
12051
12052static PyStructSequence_Field TerminalSize_fields[] = {
12053 {"columns", "width of the terminal window in characters"},
12054 {"lines", "height of the terminal window in characters"},
12055 {NULL, NULL}
12056};
12057
12058static PyStructSequence_Desc TerminalSize_desc = {
12059 "os.terminal_size",
12060 TerminalSize_docstring,
12061 TerminalSize_fields,
12062 2,
12063};
12064
12065#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100012066/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012067PyDoc_STRVAR(termsize__doc__,
12068 "Return the size of the terminal window as (columns, lines).\n" \
12069 "\n" \
12070 "The optional argument fd (default standard output) specifies\n" \
12071 "which file descriptor should be queried.\n" \
12072 "\n" \
12073 "If the file descriptor is not connected to a terminal, an OSError\n" \
12074 "is thrown.\n" \
12075 "\n" \
12076 "This function will only be defined if an implementation is\n" \
12077 "available for this system.\n" \
12078 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080012079 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012080 "normally be used, os.get_terminal_size is the low-level implementation.");
12081
12082static PyObject*
12083get_terminal_size(PyObject *self, PyObject *args)
12084{
12085 int columns, lines;
12086 PyObject *termsize;
12087
12088 int fd = fileno(stdout);
12089 /* Under some conditions stdout may not be connected and
12090 * fileno(stdout) may point to an invalid file descriptor. For example
12091 * GUI apps don't have valid standard streams by default.
12092 *
12093 * If this happens, and the optional fd argument is not present,
12094 * the ioctl below will fail returning EBADF. This is what we want.
12095 */
12096
12097 if (!PyArg_ParseTuple(args, "|i", &fd))
12098 return NULL;
12099
12100#ifdef TERMSIZE_USE_IOCTL
12101 {
12102 struct winsize w;
12103 if (ioctl(fd, TIOCGWINSZ, &w))
12104 return PyErr_SetFromErrno(PyExc_OSError);
12105 columns = w.ws_col;
12106 lines = w.ws_row;
12107 }
12108#endif /* TERMSIZE_USE_IOCTL */
12109
12110#ifdef TERMSIZE_USE_CONIO
12111 {
12112 DWORD nhandle;
12113 HANDLE handle;
12114 CONSOLE_SCREEN_BUFFER_INFO csbi;
12115 switch (fd) {
12116 case 0: nhandle = STD_INPUT_HANDLE;
12117 break;
12118 case 1: nhandle = STD_OUTPUT_HANDLE;
12119 break;
12120 case 2: nhandle = STD_ERROR_HANDLE;
12121 break;
12122 default:
12123 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12124 }
12125 handle = GetStdHandle(nhandle);
12126 if (handle == NULL)
12127 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12128 if (handle == INVALID_HANDLE_VALUE)
12129 return PyErr_SetFromWindowsErr(0);
12130
12131 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12132 return PyErr_SetFromWindowsErr(0);
12133
12134 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12135 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12136 }
12137#endif /* TERMSIZE_USE_CONIO */
12138
Eddie Elizondo474eedf2018-11-13 04:09:31 -080012139 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012140 if (termsize == NULL)
12141 return NULL;
12142 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12143 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12144 if (PyErr_Occurred()) {
12145 Py_DECREF(termsize);
12146 return NULL;
12147 }
12148 return termsize;
12149}
12150#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12151
Larry Hastings2f936352014-08-05 14:04:04 +100012152
12153/*[clinic input]
12154os.cpu_count
12155
Charles-François Natali80d62e62015-08-13 20:37:08 +010012156Return the number of CPUs in the system; return None if indeterminable.
12157
12158This number is not equivalent to the number of CPUs the current process can
12159use. The number of usable CPUs can be obtained with
12160``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012161[clinic start generated code]*/
12162
Larry Hastings2f936352014-08-05 14:04:04 +100012163static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012164os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012165/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012166{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012167 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012168#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012169 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
12170 Need to fallback to Vista behavior if this call isn't present */
12171 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012172 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010012173 Py_BEGIN_ALLOW_THREADS
12174 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012175 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
12176 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010012177 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040012178 if (_GetMaximumProcessorCount != NULL) {
12179 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
12180 }
12181 else {
12182 SYSTEM_INFO sysinfo;
12183 GetSystemInfo(&sysinfo);
12184 ncpu = sysinfo.dwNumberOfProcessors;
12185 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012186#elif defined(__hpux)
12187 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12188#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12189 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012190#elif defined(__DragonFly__) || \
12191 defined(__OpenBSD__) || \
12192 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012193 defined(__NetBSD__) || \
12194 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012195 int mib[2];
12196 size_t len = sizeof(ncpu);
12197 mib[0] = CTL_HW;
12198 mib[1] = HW_NCPU;
12199 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12200 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012201#endif
12202 if (ncpu >= 1)
12203 return PyLong_FromLong(ncpu);
12204 else
12205 Py_RETURN_NONE;
12206}
12207
Victor Stinnerdaf45552013-08-28 00:53:59 +020012208
Larry Hastings2f936352014-08-05 14:04:04 +100012209/*[clinic input]
12210os.get_inheritable -> bool
12211
12212 fd: int
12213 /
12214
12215Get the close-on-exe flag of the specified file descriptor.
12216[clinic start generated code]*/
12217
Larry Hastings2f936352014-08-05 14:04:04 +100012218static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012219os_get_inheritable_impl(PyObject *module, int fd)
12220/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012221{
Steve Dower8fc89802015-04-12 00:26:27 -040012222 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012223 _Py_BEGIN_SUPPRESS_IPH
12224 return_value = _Py_get_inheritable(fd);
12225 _Py_END_SUPPRESS_IPH
12226 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012227}
12228
12229
12230/*[clinic input]
12231os.set_inheritable
12232 fd: int
12233 inheritable: int
12234 /
12235
12236Set the inheritable flag of the specified file descriptor.
12237[clinic start generated code]*/
12238
Larry Hastings2f936352014-08-05 14:04:04 +100012239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012240os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12241/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012242{
Steve Dower8fc89802015-04-12 00:26:27 -040012243 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012244
Steve Dower8fc89802015-04-12 00:26:27 -040012245 _Py_BEGIN_SUPPRESS_IPH
12246 result = _Py_set_inheritable(fd, inheritable, NULL);
12247 _Py_END_SUPPRESS_IPH
12248 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012249 return NULL;
12250 Py_RETURN_NONE;
12251}
12252
12253
12254#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012255/*[clinic input]
12256os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012257 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012258 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012259
Larry Hastings2f936352014-08-05 14:04:04 +100012260Get the close-on-exe flag of the specified file descriptor.
12261[clinic start generated code]*/
12262
Larry Hastings2f936352014-08-05 14:04:04 +100012263static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012264os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012265/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012266{
12267 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012268
12269 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12270 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012271 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012272 }
12273
Larry Hastings2f936352014-08-05 14:04:04 +100012274 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012275}
12276
Victor Stinnerdaf45552013-08-28 00:53:59 +020012277
Larry Hastings2f936352014-08-05 14:04:04 +100012278/*[clinic input]
12279os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012280 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012281 inheritable: bool
12282 /
12283
12284Set the inheritable flag of the specified handle.
12285[clinic start generated code]*/
12286
Larry Hastings2f936352014-08-05 14:04:04 +100012287static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012288os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012289 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012290/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012291{
12292 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012293 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12294 PyErr_SetFromWindowsErr(0);
12295 return NULL;
12296 }
12297 Py_RETURN_NONE;
12298}
Larry Hastings2f936352014-08-05 14:04:04 +100012299#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012300
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012301#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012302/*[clinic input]
12303os.get_blocking -> bool
12304 fd: int
12305 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012306
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012307Get the blocking mode of the file descriptor.
12308
12309Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12310[clinic start generated code]*/
12311
12312static int
12313os_get_blocking_impl(PyObject *module, int fd)
12314/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012315{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012316 int blocking;
12317
Steve Dower8fc89802015-04-12 00:26:27 -040012318 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012319 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012320 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012321 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012322}
12323
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012324/*[clinic input]
12325os.set_blocking
12326 fd: int
12327 blocking: bool(accept={int})
12328 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012329
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012330Set the blocking mode of the specified file descriptor.
12331
12332Set the O_NONBLOCK flag if blocking is False,
12333clear the O_NONBLOCK flag otherwise.
12334[clinic start generated code]*/
12335
12336static PyObject *
12337os_set_blocking_impl(PyObject *module, int fd, int blocking)
12338/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012339{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012340 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012341
Steve Dower8fc89802015-04-12 00:26:27 -040012342 _Py_BEGIN_SUPPRESS_IPH
12343 result = _Py_set_blocking(fd, blocking);
12344 _Py_END_SUPPRESS_IPH
12345 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012346 return NULL;
12347 Py_RETURN_NONE;
12348}
12349#endif /* !MS_WINDOWS */
12350
12351
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012352/*[clinic input]
12353class os.DirEntry "DirEntry *" "&DirEntryType"
12354[clinic start generated code]*/
12355/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012356
12357typedef struct {
12358 PyObject_HEAD
12359 PyObject *name;
12360 PyObject *path;
12361 PyObject *stat;
12362 PyObject *lstat;
12363#ifdef MS_WINDOWS
12364 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012365 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012366 int got_file_index;
12367#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012368#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012369 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012370#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012371 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012372 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012373#endif
12374} DirEntry;
12375
12376static void
12377DirEntry_dealloc(DirEntry *entry)
12378{
12379 Py_XDECREF(entry->name);
12380 Py_XDECREF(entry->path);
12381 Py_XDECREF(entry->stat);
12382 Py_XDECREF(entry->lstat);
12383 Py_TYPE(entry)->tp_free((PyObject *)entry);
12384}
12385
12386/* Forward reference */
12387static int
12388DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12389
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012390/*[clinic input]
12391os.DirEntry.is_symlink -> bool
12392
12393Return True if the entry is a symbolic link; cached per entry.
12394[clinic start generated code]*/
12395
Victor Stinner6036e442015-03-08 01:58:04 +010012396static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012397os_DirEntry_is_symlink_impl(DirEntry *self)
12398/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012399{
12400#ifdef MS_WINDOWS
12401 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012402#elif defined(HAVE_DIRENT_D_TYPE)
12403 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012404 if (self->d_type != DT_UNKNOWN)
12405 return self->d_type == DT_LNK;
12406 else
12407 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012408#else
12409 /* POSIX without d_type */
12410 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012411#endif
12412}
12413
12414static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012415DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12416{
12417 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012418 STRUCT_STAT st;
12419 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012420
12421#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012422 if (!PyUnicode_FSDecoder(self->path, &ub))
12423 return NULL;
12424 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012425#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012426 if (!PyUnicode_FSConverter(self->path, &ub))
12427 return NULL;
12428 const char *path = PyBytes_AS_STRING(ub);
12429 if (self->dir_fd != DEFAULT_DIR_FD) {
12430#ifdef HAVE_FSTATAT
12431 result = fstatat(self->dir_fd, path, &st,
12432 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12433#else
12434 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12435 return NULL;
12436#endif /* HAVE_FSTATAT */
12437 }
12438 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012439#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012440 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012441 if (follow_symlinks)
12442 result = STAT(path, &st);
12443 else
12444 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012445 }
12446 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012447
12448 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012449 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012450
12451 return _pystat_fromstructstat(&st);
12452}
12453
12454static PyObject *
12455DirEntry_get_lstat(DirEntry *self)
12456{
12457 if (!self->lstat) {
12458#ifdef MS_WINDOWS
12459 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12460#else /* POSIX */
12461 self->lstat = DirEntry_fetch_stat(self, 0);
12462#endif
12463 }
12464 Py_XINCREF(self->lstat);
12465 return self->lstat;
12466}
12467
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012468/*[clinic input]
12469os.DirEntry.stat
12470 *
12471 follow_symlinks: bool = True
12472
12473Return stat_result object for the entry; cached per entry.
12474[clinic start generated code]*/
12475
Victor Stinner6036e442015-03-08 01:58:04 +010012476static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012477os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12478/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012479{
12480 if (!follow_symlinks)
12481 return DirEntry_get_lstat(self);
12482
12483 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012484 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012485 if (result == -1)
12486 return NULL;
12487 else if (result)
12488 self->stat = DirEntry_fetch_stat(self, 1);
12489 else
12490 self->stat = DirEntry_get_lstat(self);
12491 }
12492
12493 Py_XINCREF(self->stat);
12494 return self->stat;
12495}
12496
Victor Stinner6036e442015-03-08 01:58:04 +010012497/* Set exception and return -1 on error, 0 for False, 1 for True */
12498static int
12499DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12500{
12501 PyObject *stat = NULL;
12502 PyObject *st_mode = NULL;
12503 long mode;
12504 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012505#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012506 int is_symlink;
12507 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012508#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012509#ifdef MS_WINDOWS
12510 unsigned long dir_bits;
12511#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012512 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012513
12514#ifdef MS_WINDOWS
12515 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12516 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012517#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012518 is_symlink = self->d_type == DT_LNK;
12519 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12520#endif
12521
Victor Stinner35a97c02015-03-08 02:59:09 +010012522#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012523 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012524#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012525 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012526 if (!stat) {
12527 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12528 /* If file doesn't exist (anymore), then return False
12529 (i.e., say it's not a file/directory) */
12530 PyErr_Clear();
12531 return 0;
12532 }
12533 goto error;
12534 }
12535 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12536 if (!st_mode)
12537 goto error;
12538
12539 mode = PyLong_AsLong(st_mode);
12540 if (mode == -1 && PyErr_Occurred())
12541 goto error;
12542 Py_CLEAR(st_mode);
12543 Py_CLEAR(stat);
12544 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012545#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012546 }
12547 else if (is_symlink) {
12548 assert(mode_bits != S_IFLNK);
12549 result = 0;
12550 }
12551 else {
12552 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12553#ifdef MS_WINDOWS
12554 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12555 if (mode_bits == S_IFDIR)
12556 result = dir_bits != 0;
12557 else
12558 result = dir_bits == 0;
12559#else /* POSIX */
12560 if (mode_bits == S_IFDIR)
12561 result = self->d_type == DT_DIR;
12562 else
12563 result = self->d_type == DT_REG;
12564#endif
12565 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012566#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012567
12568 return result;
12569
12570error:
12571 Py_XDECREF(st_mode);
12572 Py_XDECREF(stat);
12573 return -1;
12574}
12575
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012576/*[clinic input]
12577os.DirEntry.is_dir -> bool
12578 *
12579 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012580
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012581Return True if the entry is a directory; cached per entry.
12582[clinic start generated code]*/
12583
12584static int
12585os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12586/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12587{
12588 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012589}
12590
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012591/*[clinic input]
12592os.DirEntry.is_file -> bool
12593 *
12594 follow_symlinks: bool = True
12595
12596Return True if the entry is a file; cached per entry.
12597[clinic start generated code]*/
12598
12599static int
12600os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12601/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012602{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012603 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012604}
12605
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012606/*[clinic input]
12607os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012608
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012609Return inode of the entry; cached per entry.
12610[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012611
12612static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012613os_DirEntry_inode_impl(DirEntry *self)
12614/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012615{
12616#ifdef MS_WINDOWS
12617 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012618 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012619 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012620 STRUCT_STAT stat;
12621 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012622
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012623 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012624 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012625 path = PyUnicode_AsUnicode(unicode);
12626 result = LSTAT(path, &stat);
12627 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012628
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012629 if (result != 0)
12630 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012631
12632 self->win32_file_index = stat.st_ino;
12633 self->got_file_index = 1;
12634 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012635 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12636 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012637#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012638 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12639 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012640#endif
12641}
12642
12643static PyObject *
12644DirEntry_repr(DirEntry *self)
12645{
12646 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12647}
12648
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012649/*[clinic input]
12650os.DirEntry.__fspath__
12651
12652Returns the path for the entry.
12653[clinic start generated code]*/
12654
Brett Cannon96881cd2016-06-10 14:37:21 -070012655static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012656os_DirEntry___fspath___impl(DirEntry *self)
12657/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012658{
12659 Py_INCREF(self->path);
12660 return self->path;
12661}
12662
Victor Stinner6036e442015-03-08 01:58:04 +010012663static PyMemberDef DirEntry_members[] = {
12664 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12665 "the entry's base filename, relative to scandir() \"path\" argument"},
12666 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12667 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12668 {NULL}
12669};
12670
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012671#include "clinic/posixmodule.c.h"
12672
Victor Stinner6036e442015-03-08 01:58:04 +010012673static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012674 OS_DIRENTRY_IS_DIR_METHODDEF
12675 OS_DIRENTRY_IS_FILE_METHODDEF
12676 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12677 OS_DIRENTRY_STAT_METHODDEF
12678 OS_DIRENTRY_INODE_METHODDEF
12679 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012680 {NULL}
12681};
12682
Benjamin Peterson5646de42015-04-12 17:56:34 -040012683static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012684 PyVarObject_HEAD_INIT(NULL, 0)
12685 MODNAME ".DirEntry", /* tp_name */
12686 sizeof(DirEntry), /* tp_basicsize */
12687 0, /* tp_itemsize */
12688 /* methods */
12689 (destructor)DirEntry_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012690 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010012691 0, /* tp_getattr */
12692 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020012693 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010012694 (reprfunc)DirEntry_repr, /* tp_repr */
12695 0, /* tp_as_number */
12696 0, /* tp_as_sequence */
12697 0, /* tp_as_mapping */
12698 0, /* tp_hash */
12699 0, /* tp_call */
12700 0, /* tp_str */
12701 0, /* tp_getattro */
12702 0, /* tp_setattro */
12703 0, /* tp_as_buffer */
12704 Py_TPFLAGS_DEFAULT, /* tp_flags */
12705 0, /* tp_doc */
12706 0, /* tp_traverse */
12707 0, /* tp_clear */
12708 0, /* tp_richcompare */
12709 0, /* tp_weaklistoffset */
12710 0, /* tp_iter */
12711 0, /* tp_iternext */
12712 DirEntry_methods, /* tp_methods */
12713 DirEntry_members, /* tp_members */
12714};
12715
12716#ifdef MS_WINDOWS
12717
12718static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012719join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012720{
12721 Py_ssize_t path_len;
12722 Py_ssize_t size;
12723 wchar_t *result;
12724 wchar_t ch;
12725
12726 if (!path_wide) { /* Default arg: "." */
12727 path_wide = L".";
12728 path_len = 1;
12729 }
12730 else {
12731 path_len = wcslen(path_wide);
12732 }
12733
12734 /* The +1's are for the path separator and the NUL */
12735 size = path_len + 1 + wcslen(filename) + 1;
12736 result = PyMem_New(wchar_t, size);
12737 if (!result) {
12738 PyErr_NoMemory();
12739 return NULL;
12740 }
12741 wcscpy(result, path_wide);
12742 if (path_len > 0) {
12743 ch = result[path_len - 1];
12744 if (ch != SEP && ch != ALTSEP && ch != L':')
12745 result[path_len++] = SEP;
12746 wcscpy(result + path_len, filename);
12747 }
12748 return result;
12749}
12750
12751static PyObject *
12752DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12753{
12754 DirEntry *entry;
12755 BY_HANDLE_FILE_INFORMATION file_info;
12756 ULONG reparse_tag;
12757 wchar_t *joined_path;
12758
12759 entry = PyObject_New(DirEntry, &DirEntryType);
12760 if (!entry)
12761 return NULL;
12762 entry->name = NULL;
12763 entry->path = NULL;
12764 entry->stat = NULL;
12765 entry->lstat = NULL;
12766 entry->got_file_index = 0;
12767
12768 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12769 if (!entry->name)
12770 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012771 if (path->narrow) {
12772 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12773 if (!entry->name)
12774 goto error;
12775 }
Victor Stinner6036e442015-03-08 01:58:04 +010012776
12777 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12778 if (!joined_path)
12779 goto error;
12780
12781 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12782 PyMem_Free(joined_path);
12783 if (!entry->path)
12784 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012785 if (path->narrow) {
12786 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12787 if (!entry->path)
12788 goto error;
12789 }
Victor Stinner6036e442015-03-08 01:58:04 +010012790
Steve Dowercc16be82016-09-08 10:35:16 -070012791 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012792 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12793
12794 return (PyObject *)entry;
12795
12796error:
12797 Py_DECREF(entry);
12798 return NULL;
12799}
12800
12801#else /* POSIX */
12802
12803static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012804join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012805{
12806 Py_ssize_t path_len;
12807 Py_ssize_t size;
12808 char *result;
12809
12810 if (!path_narrow) { /* Default arg: "." */
12811 path_narrow = ".";
12812 path_len = 1;
12813 }
12814 else {
12815 path_len = strlen(path_narrow);
12816 }
12817
12818 if (filename_len == -1)
12819 filename_len = strlen(filename);
12820
12821 /* The +1's are for the path separator and the NUL */
12822 size = path_len + 1 + filename_len + 1;
12823 result = PyMem_New(char, size);
12824 if (!result) {
12825 PyErr_NoMemory();
12826 return NULL;
12827 }
12828 strcpy(result, path_narrow);
12829 if (path_len > 0 && result[path_len - 1] != '/')
12830 result[path_len++] = '/';
12831 strcpy(result + path_len, filename);
12832 return result;
12833}
12834
12835static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012836DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012837 ino_t d_ino
12838#ifdef HAVE_DIRENT_D_TYPE
12839 , unsigned char d_type
12840#endif
12841 )
Victor Stinner6036e442015-03-08 01:58:04 +010012842{
12843 DirEntry *entry;
12844 char *joined_path;
12845
12846 entry = PyObject_New(DirEntry, &DirEntryType);
12847 if (!entry)
12848 return NULL;
12849 entry->name = NULL;
12850 entry->path = NULL;
12851 entry->stat = NULL;
12852 entry->lstat = NULL;
12853
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012854 if (path->fd != -1) {
12855 entry->dir_fd = path->fd;
12856 joined_path = NULL;
12857 }
12858 else {
12859 entry->dir_fd = DEFAULT_DIR_FD;
12860 joined_path = join_path_filename(path->narrow, name, name_len);
12861 if (!joined_path)
12862 goto error;
12863 }
Victor Stinner6036e442015-03-08 01:58:04 +010012864
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012865 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012866 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012867 if (joined_path)
12868 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012869 }
12870 else {
12871 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012872 if (joined_path)
12873 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012874 }
12875 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012876 if (!entry->name)
12877 goto error;
12878
12879 if (path->fd != -1) {
12880 entry->path = entry->name;
12881 Py_INCREF(entry->path);
12882 }
12883 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012884 goto error;
12885
Victor Stinner35a97c02015-03-08 02:59:09 +010012886#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012887 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012888#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012889 entry->d_ino = d_ino;
12890
12891 return (PyObject *)entry;
12892
12893error:
12894 Py_XDECREF(entry);
12895 return NULL;
12896}
12897
12898#endif
12899
12900
12901typedef struct {
12902 PyObject_HEAD
12903 path_t path;
12904#ifdef MS_WINDOWS
12905 HANDLE handle;
12906 WIN32_FIND_DATAW file_data;
12907 int first_time;
12908#else /* POSIX */
12909 DIR *dirp;
12910#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012911#ifdef HAVE_FDOPENDIR
12912 int fd;
12913#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012914} ScandirIterator;
12915
12916#ifdef MS_WINDOWS
12917
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012918static int
12919ScandirIterator_is_closed(ScandirIterator *iterator)
12920{
12921 return iterator->handle == INVALID_HANDLE_VALUE;
12922}
12923
Victor Stinner6036e442015-03-08 01:58:04 +010012924static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012925ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012926{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012927 HANDLE handle = iterator->handle;
12928
12929 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012930 return;
12931
Victor Stinner6036e442015-03-08 01:58:04 +010012932 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012933 Py_BEGIN_ALLOW_THREADS
12934 FindClose(handle);
12935 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012936}
12937
12938static PyObject *
12939ScandirIterator_iternext(ScandirIterator *iterator)
12940{
12941 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12942 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012943 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012944
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012945 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012946 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012947 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012948
12949 while (1) {
12950 if (!iterator->first_time) {
12951 Py_BEGIN_ALLOW_THREADS
12952 success = FindNextFileW(iterator->handle, file_data);
12953 Py_END_ALLOW_THREADS
12954 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012955 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012956 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012957 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012958 break;
12959 }
12960 }
12961 iterator->first_time = 0;
12962
12963 /* Skip over . and .. */
12964 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012965 wcscmp(file_data->cFileName, L"..") != 0) {
12966 entry = DirEntry_from_find_data(&iterator->path, file_data);
12967 if (!entry)
12968 break;
12969 return entry;
12970 }
Victor Stinner6036e442015-03-08 01:58:04 +010012971
12972 /* Loop till we get a non-dot directory or finish iterating */
12973 }
12974
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012975 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012976 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012977 return NULL;
12978}
12979
12980#else /* POSIX */
12981
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012982static int
12983ScandirIterator_is_closed(ScandirIterator *iterator)
12984{
12985 return !iterator->dirp;
12986}
12987
Victor Stinner6036e442015-03-08 01:58:04 +010012988static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012989ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012990{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012991 DIR *dirp = iterator->dirp;
12992
12993 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012994 return;
12995
Victor Stinner6036e442015-03-08 01:58:04 +010012996 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012997 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012998#ifdef HAVE_FDOPENDIR
12999 if (iterator->path.fd != -1)
13000 rewinddir(dirp);
13001#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013002 closedir(dirp);
13003 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013004 return;
13005}
13006
13007static PyObject *
13008ScandirIterator_iternext(ScandirIterator *iterator)
13009{
13010 struct dirent *direntp;
13011 Py_ssize_t name_len;
13012 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013013 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013014
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013015 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013016 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013017 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013018
13019 while (1) {
13020 errno = 0;
13021 Py_BEGIN_ALLOW_THREADS
13022 direntp = readdir(iterator->dirp);
13023 Py_END_ALLOW_THREADS
13024
13025 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013026 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013027 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013028 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013029 break;
13030 }
13031
13032 /* Skip over . and .. */
13033 name_len = NAMLEN(direntp);
13034 is_dot = direntp->d_name[0] == '.' &&
13035 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13036 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013037 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010013038 name_len, direntp->d_ino
13039#ifdef HAVE_DIRENT_D_TYPE
13040 , direntp->d_type
13041#endif
13042 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013043 if (!entry)
13044 break;
13045 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013046 }
13047
13048 /* Loop till we get a non-dot directory or finish iterating */
13049 }
13050
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013051 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013052 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013053 return NULL;
13054}
13055
13056#endif
13057
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013058static PyObject *
13059ScandirIterator_close(ScandirIterator *self, PyObject *args)
13060{
13061 ScandirIterator_closedir(self);
13062 Py_RETURN_NONE;
13063}
13064
13065static PyObject *
13066ScandirIterator_enter(PyObject *self, PyObject *args)
13067{
13068 Py_INCREF(self);
13069 return self;
13070}
13071
13072static PyObject *
13073ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13074{
13075 ScandirIterator_closedir(self);
13076 Py_RETURN_NONE;
13077}
13078
Victor Stinner6036e442015-03-08 01:58:04 +010013079static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013080ScandirIterator_finalize(ScandirIterator *iterator)
13081{
13082 PyObject *error_type, *error_value, *error_traceback;
13083
13084 /* Save the current exception, if any. */
13085 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13086
13087 if (!ScandirIterator_is_closed(iterator)) {
13088 ScandirIterator_closedir(iterator);
13089
13090 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13091 "unclosed scandir iterator %R", iterator)) {
13092 /* Spurious errors can appear at shutdown */
13093 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13094 PyErr_WriteUnraisable((PyObject *) iterator);
13095 }
13096 }
13097 }
13098
Victor Stinner7bfa4092016-03-23 00:43:54 +010013099 path_cleanup(&iterator->path);
13100
13101 /* Restore the saved exception. */
13102 PyErr_Restore(error_type, error_value, error_traceback);
13103}
13104
13105static void
Victor Stinner6036e442015-03-08 01:58:04 +010013106ScandirIterator_dealloc(ScandirIterator *iterator)
13107{
Victor Stinner7bfa4092016-03-23 00:43:54 +010013108 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13109 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013110
Victor Stinner6036e442015-03-08 01:58:04 +010013111 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
13112}
13113
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013114static PyMethodDef ScandirIterator_methods[] = {
13115 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13116 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13117 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13118 {NULL}
13119};
13120
Benjamin Peterson5646de42015-04-12 17:56:34 -040013121static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010013122 PyVarObject_HEAD_INIT(NULL, 0)
13123 MODNAME ".ScandirIterator", /* tp_name */
13124 sizeof(ScandirIterator), /* tp_basicsize */
13125 0, /* tp_itemsize */
13126 /* methods */
13127 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013128 0, /* tp_vectorcall_offset */
Victor Stinner6036e442015-03-08 01:58:04 +010013129 0, /* tp_getattr */
13130 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +020013131 0, /* tp_as_async */
Victor Stinner6036e442015-03-08 01:58:04 +010013132 0, /* tp_repr */
13133 0, /* tp_as_number */
13134 0, /* tp_as_sequence */
13135 0, /* tp_as_mapping */
13136 0, /* tp_hash */
13137 0, /* tp_call */
13138 0, /* tp_str */
13139 0, /* tp_getattro */
13140 0, /* tp_setattro */
13141 0, /* tp_as_buffer */
Antoine Pitrouada319b2019-05-29 22:12:38 +020013142 Py_TPFLAGS_DEFAULT, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010013143 0, /* tp_doc */
13144 0, /* tp_traverse */
13145 0, /* tp_clear */
13146 0, /* tp_richcompare */
13147 0, /* tp_weaklistoffset */
13148 PyObject_SelfIter, /* tp_iter */
13149 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013150 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010013151 0, /* tp_members */
13152 0, /* tp_getset */
13153 0, /* tp_base */
13154 0, /* tp_dict */
13155 0, /* tp_descr_get */
13156 0, /* tp_descr_set */
13157 0, /* tp_dictoffset */
13158 0, /* tp_init */
13159 0, /* tp_alloc */
13160 0, /* tp_new */
13161 0, /* tp_free */
13162 0, /* tp_is_gc */
13163 0, /* tp_bases */
13164 0, /* tp_mro */
13165 0, /* tp_cache */
13166 0, /* tp_subclasses */
13167 0, /* tp_weaklist */
13168 0, /* tp_del */
13169 0, /* tp_version_tag */
13170 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010013171};
13172
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013173/*[clinic input]
13174os.scandir
13175
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013176 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013177
13178Return an iterator of DirEntry objects for given path.
13179
BNMetricsb9427072018-11-02 15:20:19 +000013180path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013181is bytes, the names of yielded DirEntry objects will also be bytes; in
13182all other circumstances they will be str.
13183
13184If path is None, uses the path='.'.
13185[clinic start generated code]*/
13186
Victor Stinner6036e442015-03-08 01:58:04 +010013187static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013188os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013189/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013190{
13191 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013192#ifdef MS_WINDOWS
13193 wchar_t *path_strW;
13194#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013195 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013196#ifdef HAVE_FDOPENDIR
13197 int fd = -1;
13198#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013199#endif
13200
Steve Dower60419a72019-06-24 08:42:54 -070013201 if (PySys_Audit("os.scandir", "O",
13202 path->object ? path->object : Py_None) < 0) {
13203 return NULL;
13204 }
13205
Victor Stinner6036e442015-03-08 01:58:04 +010013206 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
13207 if (!iterator)
13208 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013209
13210#ifdef MS_WINDOWS
13211 iterator->handle = INVALID_HANDLE_VALUE;
13212#else
13213 iterator->dirp = NULL;
13214#endif
13215
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013216 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013217 /* Move the ownership to iterator->path */
13218 path->object = NULL;
13219 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013220
13221#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013222 iterator->first_time = 1;
13223
13224 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13225 if (!path_strW)
13226 goto error;
13227
13228 Py_BEGIN_ALLOW_THREADS
13229 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13230 Py_END_ALLOW_THREADS
13231
13232 PyMem_Free(path_strW);
13233
13234 if (iterator->handle == INVALID_HANDLE_VALUE) {
13235 path_error(&iterator->path);
13236 goto error;
13237 }
13238#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013239 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013240#ifdef HAVE_FDOPENDIR
13241 if (path->fd != -1) {
13242 /* closedir() closes the FD, so we duplicate it */
13243 fd = _Py_dup(path->fd);
13244 if (fd == -1)
13245 goto error;
13246
13247 Py_BEGIN_ALLOW_THREADS
13248 iterator->dirp = fdopendir(fd);
13249 Py_END_ALLOW_THREADS
13250 }
13251 else
13252#endif
13253 {
13254 if (iterator->path.narrow)
13255 path_str = iterator->path.narrow;
13256 else
13257 path_str = ".";
13258
13259 Py_BEGIN_ALLOW_THREADS
13260 iterator->dirp = opendir(path_str);
13261 Py_END_ALLOW_THREADS
13262 }
Victor Stinner6036e442015-03-08 01:58:04 +010013263
13264 if (!iterator->dirp) {
13265 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013266#ifdef HAVE_FDOPENDIR
13267 if (fd != -1) {
13268 Py_BEGIN_ALLOW_THREADS
13269 close(fd);
13270 Py_END_ALLOW_THREADS
13271 }
13272#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013273 goto error;
13274 }
13275#endif
13276
13277 return (PyObject *)iterator;
13278
13279error:
13280 Py_DECREF(iterator);
13281 return NULL;
13282}
13283
Ethan Furman410ef8e2016-06-04 12:06:26 -070013284/*
13285 Return the file system path representation of the object.
13286
13287 If the object is str or bytes, then allow it to pass through with
13288 an incremented refcount. If the object defines __fspath__(), then
13289 return the result of that method. All other types raise a TypeError.
13290*/
13291PyObject *
13292PyOS_FSPath(PyObject *path)
13293{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013294 /* For error message reasons, this function is manually inlined in
13295 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013296 _Py_IDENTIFIER(__fspath__);
13297 PyObject *func = NULL;
13298 PyObject *path_repr = NULL;
13299
13300 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13301 Py_INCREF(path);
13302 return path;
13303 }
13304
13305 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13306 if (NULL == func) {
13307 return PyErr_Format(PyExc_TypeError,
13308 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013309 "not %.200s",
13310 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013311 }
13312
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013313 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013314 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013315 if (NULL == path_repr) {
13316 return NULL;
13317 }
13318
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013319 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13320 PyErr_Format(PyExc_TypeError,
13321 "expected %.200s.__fspath__() to return str or bytes, "
13322 "not %.200s", Py_TYPE(path)->tp_name,
13323 Py_TYPE(path_repr)->tp_name);
13324 Py_DECREF(path_repr);
13325 return NULL;
13326 }
13327
Ethan Furman410ef8e2016-06-04 12:06:26 -070013328 return path_repr;
13329}
13330
13331/*[clinic input]
13332os.fspath
13333
13334 path: object
13335
13336Return the file system path representation of the object.
13337
Brett Cannonb4f43e92016-06-09 14:32:08 -070013338If the object is str or bytes, then allow it to pass through as-is. If the
13339object defines __fspath__(), then return the result of that method. All other
13340types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013341[clinic start generated code]*/
13342
13343static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013344os_fspath_impl(PyObject *module, PyObject *path)
13345/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013346{
13347 return PyOS_FSPath(path);
13348}
Victor Stinner6036e442015-03-08 01:58:04 +010013349
Victor Stinner9b1f4742016-09-06 16:18:52 -070013350#ifdef HAVE_GETRANDOM_SYSCALL
13351/*[clinic input]
13352os.getrandom
13353
13354 size: Py_ssize_t
13355 flags: int=0
13356
13357Obtain a series of random bytes.
13358[clinic start generated code]*/
13359
13360static PyObject *
13361os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13362/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13363{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013364 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013365 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013366
13367 if (size < 0) {
13368 errno = EINVAL;
13369 return posix_error();
13370 }
13371
Victor Stinnerec2319c2016-09-20 23:00:59 +020013372 bytes = PyBytes_FromStringAndSize(NULL, size);
13373 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013374 PyErr_NoMemory();
13375 return NULL;
13376 }
13377
13378 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013379 n = syscall(SYS_getrandom,
13380 PyBytes_AS_STRING(bytes),
13381 PyBytes_GET_SIZE(bytes),
13382 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013383 if (n < 0 && errno == EINTR) {
13384 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013385 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013386 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013387
13388 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013389 continue;
13390 }
13391 break;
13392 }
13393
13394 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013395 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013396 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013397 }
13398
Victor Stinnerec2319c2016-09-20 23:00:59 +020013399 if (n != size) {
13400 _PyBytes_Resize(&bytes, n);
13401 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013402
13403 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013404
13405error:
13406 Py_DECREF(bytes);
13407 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013408}
13409#endif /* HAVE_GETRANDOM_SYSCALL */
13410
Steve Dower2438cdf2019-03-29 16:37:16 -070013411#ifdef MS_WINDOWS
13412/* bpo-36085: Helper functions for managing DLL search directories
13413 * on win32
13414 */
13415
13416typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13417typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13418
13419/*[clinic input]
13420os._add_dll_directory
13421
13422 path: path_t
13423
13424Add a path to the DLL search path.
13425
13426This search path is used when resolving dependencies for imported
13427extension modules (the module itself is resolved through sys.path),
13428and also by ctypes.
13429
13430Returns an opaque value that may be passed to os.remove_dll_directory
13431to remove this directory from the search path.
13432[clinic start generated code]*/
13433
13434static PyObject *
13435os__add_dll_directory_impl(PyObject *module, path_t *path)
13436/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13437{
13438 HMODULE hKernel32;
13439 PAddDllDirectory AddDllDirectory;
13440 DLL_DIRECTORY_COOKIE cookie = 0;
13441 DWORD err = 0;
13442
13443 /* For Windows 7, we have to load this. As this will be a fairly
13444 infrequent operation, just do it each time. Kernel32 is always
13445 loaded. */
13446 Py_BEGIN_ALLOW_THREADS
13447 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13448 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13449 hKernel32, "AddDllDirectory")) ||
13450 !(cookie = (*AddDllDirectory)(path->wide))) {
13451 err = GetLastError();
13452 }
13453 Py_END_ALLOW_THREADS
13454
13455 if (err) {
13456 return win32_error_object_err("add_dll_directory",
13457 path->object, err);
13458 }
13459
13460 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13461}
13462
13463/*[clinic input]
13464os._remove_dll_directory
13465
13466 cookie: object
13467
13468Removes a path from the DLL search path.
13469
13470The parameter is an opaque value that was returned from
13471os.add_dll_directory. You can only remove directories that you added
13472yourself.
13473[clinic start generated code]*/
13474
13475static PyObject *
13476os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13477/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13478{
13479 HMODULE hKernel32;
13480 PRemoveDllDirectory RemoveDllDirectory;
13481 DLL_DIRECTORY_COOKIE cookieValue;
13482 DWORD err = 0;
13483
13484 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13485 PyErr_SetString(PyExc_TypeError,
13486 "Provided cookie was not returned from os.add_dll_directory");
13487 return NULL;
13488 }
13489
13490 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13491 cookie, "DLL directory cookie");
13492
13493 /* For Windows 7, we have to load this. As this will be a fairly
13494 infrequent operation, just do it each time. Kernel32 is always
13495 loaded. */
13496 Py_BEGIN_ALLOW_THREADS
13497 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13498 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13499 hKernel32, "RemoveDllDirectory")) ||
13500 !(*RemoveDllDirectory)(cookieValue)) {
13501 err = GetLastError();
13502 }
13503 Py_END_ALLOW_THREADS
13504
13505 if (err) {
13506 return win32_error_object_err("remove_dll_directory",
13507 NULL, err);
13508 }
13509
13510 if (PyCapsule_SetName(cookie, NULL)) {
13511 return NULL;
13512 }
13513
13514 Py_RETURN_NONE;
13515}
13516
13517#endif
Larry Hastings31826802013-10-19 00:09:25 -070013518
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013519static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013520
13521 OS_STAT_METHODDEF
13522 OS_ACCESS_METHODDEF
13523 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013524 OS_CHDIR_METHODDEF
13525 OS_CHFLAGS_METHODDEF
13526 OS_CHMOD_METHODDEF
13527 OS_FCHMOD_METHODDEF
13528 OS_LCHMOD_METHODDEF
13529 OS_CHOWN_METHODDEF
13530 OS_FCHOWN_METHODDEF
13531 OS_LCHOWN_METHODDEF
13532 OS_LCHFLAGS_METHODDEF
13533 OS_CHROOT_METHODDEF
13534 OS_CTERMID_METHODDEF
13535 OS_GETCWD_METHODDEF
13536 OS_GETCWDB_METHODDEF
13537 OS_LINK_METHODDEF
13538 OS_LISTDIR_METHODDEF
13539 OS_LSTAT_METHODDEF
13540 OS_MKDIR_METHODDEF
13541 OS_NICE_METHODDEF
13542 OS_GETPRIORITY_METHODDEF
13543 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013544 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013545 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013546 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013547 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013548 OS_RENAME_METHODDEF
13549 OS_REPLACE_METHODDEF
13550 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013551 OS_SYMLINK_METHODDEF
13552 OS_SYSTEM_METHODDEF
13553 OS_UMASK_METHODDEF
13554 OS_UNAME_METHODDEF
13555 OS_UNLINK_METHODDEF
13556 OS_REMOVE_METHODDEF
13557 OS_UTIME_METHODDEF
13558 OS_TIMES_METHODDEF
13559 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013560 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013561 OS_EXECV_METHODDEF
13562 OS_EXECVE_METHODDEF
13563 OS_SPAWNV_METHODDEF
13564 OS_SPAWNVE_METHODDEF
13565 OS_FORK1_METHODDEF
13566 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013567 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013568 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13569 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13570 OS_SCHED_GETPARAM_METHODDEF
13571 OS_SCHED_GETSCHEDULER_METHODDEF
13572 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13573 OS_SCHED_SETPARAM_METHODDEF
13574 OS_SCHED_SETSCHEDULER_METHODDEF
13575 OS_SCHED_YIELD_METHODDEF
13576 OS_SCHED_SETAFFINITY_METHODDEF
13577 OS_SCHED_GETAFFINITY_METHODDEF
13578 OS_OPENPTY_METHODDEF
13579 OS_FORKPTY_METHODDEF
13580 OS_GETEGID_METHODDEF
13581 OS_GETEUID_METHODDEF
13582 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013583#ifdef HAVE_GETGROUPLIST
13584 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13585#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013586 OS_GETGROUPS_METHODDEF
13587 OS_GETPID_METHODDEF
13588 OS_GETPGRP_METHODDEF
13589 OS_GETPPID_METHODDEF
13590 OS_GETUID_METHODDEF
13591 OS_GETLOGIN_METHODDEF
13592 OS_KILL_METHODDEF
13593 OS_KILLPG_METHODDEF
13594 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013595#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013596 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013597#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013598 OS_SETUID_METHODDEF
13599 OS_SETEUID_METHODDEF
13600 OS_SETREUID_METHODDEF
13601 OS_SETGID_METHODDEF
13602 OS_SETEGID_METHODDEF
13603 OS_SETREGID_METHODDEF
13604 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013605#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013606 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013607#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013608 OS_GETPGID_METHODDEF
13609 OS_SETPGRP_METHODDEF
13610 OS_WAIT_METHODDEF
13611 OS_WAIT3_METHODDEF
13612 OS_WAIT4_METHODDEF
13613 OS_WAITID_METHODDEF
13614 OS_WAITPID_METHODDEF
13615 OS_GETSID_METHODDEF
13616 OS_SETSID_METHODDEF
13617 OS_SETPGID_METHODDEF
13618 OS_TCGETPGRP_METHODDEF
13619 OS_TCSETPGRP_METHODDEF
13620 OS_OPEN_METHODDEF
13621 OS_CLOSE_METHODDEF
13622 OS_CLOSERANGE_METHODDEF
13623 OS_DEVICE_ENCODING_METHODDEF
13624 OS_DUP_METHODDEF
13625 OS_DUP2_METHODDEF
13626 OS_LOCKF_METHODDEF
13627 OS_LSEEK_METHODDEF
13628 OS_READ_METHODDEF
13629 OS_READV_METHODDEF
13630 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013631 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013632 OS_WRITE_METHODDEF
13633 OS_WRITEV_METHODDEF
13634 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013635 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013636#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013637 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013638 posix_sendfile__doc__},
13639#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013640 OS_FSTAT_METHODDEF
13641 OS_ISATTY_METHODDEF
13642 OS_PIPE_METHODDEF
13643 OS_PIPE2_METHODDEF
13644 OS_MKFIFO_METHODDEF
13645 OS_MKNOD_METHODDEF
13646 OS_MAJOR_METHODDEF
13647 OS_MINOR_METHODDEF
13648 OS_MAKEDEV_METHODDEF
13649 OS_FTRUNCATE_METHODDEF
13650 OS_TRUNCATE_METHODDEF
13651 OS_POSIX_FALLOCATE_METHODDEF
13652 OS_POSIX_FADVISE_METHODDEF
13653 OS_PUTENV_METHODDEF
13654 OS_UNSETENV_METHODDEF
13655 OS_STRERROR_METHODDEF
13656 OS_FCHDIR_METHODDEF
13657 OS_FSYNC_METHODDEF
13658 OS_SYNC_METHODDEF
13659 OS_FDATASYNC_METHODDEF
13660 OS_WCOREDUMP_METHODDEF
13661 OS_WIFCONTINUED_METHODDEF
13662 OS_WIFSTOPPED_METHODDEF
13663 OS_WIFSIGNALED_METHODDEF
13664 OS_WIFEXITED_METHODDEF
13665 OS_WEXITSTATUS_METHODDEF
13666 OS_WTERMSIG_METHODDEF
13667 OS_WSTOPSIG_METHODDEF
13668 OS_FSTATVFS_METHODDEF
13669 OS_STATVFS_METHODDEF
13670 OS_CONFSTR_METHODDEF
13671 OS_SYSCONF_METHODDEF
13672 OS_FPATHCONF_METHODDEF
13673 OS_PATHCONF_METHODDEF
13674 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013675 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013676 OS__GETDISKUSAGE_METHODDEF
13677 OS__GETFINALPATHNAME_METHODDEF
13678 OS__GETVOLUMEPATHNAME_METHODDEF
13679 OS_GETLOADAVG_METHODDEF
13680 OS_URANDOM_METHODDEF
13681 OS_SETRESUID_METHODDEF
13682 OS_SETRESGID_METHODDEF
13683 OS_GETRESUID_METHODDEF
13684 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013685
Larry Hastings2f936352014-08-05 14:04:04 +100013686 OS_GETXATTR_METHODDEF
13687 OS_SETXATTR_METHODDEF
13688 OS_REMOVEXATTR_METHODDEF
13689 OS_LISTXATTR_METHODDEF
13690
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013691#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13692 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13693#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013694 OS_CPU_COUNT_METHODDEF
13695 OS_GET_INHERITABLE_METHODDEF
13696 OS_SET_INHERITABLE_METHODDEF
13697 OS_GET_HANDLE_INHERITABLE_METHODDEF
13698 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013699#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013700 OS_GET_BLOCKING_METHODDEF
13701 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013702#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013703 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013704 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013705 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013706 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013707#ifdef MS_WINDOWS
13708 OS__ADD_DLL_DIRECTORY_METHODDEF
13709 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13710#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013711 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013712};
13713
Barry Warsaw4a342091996-12-19 23:50:02 +000013714static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013715all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013716{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013717#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013718 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013719#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013720#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013721 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013722#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013723#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013724 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013725#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013726#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013727 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013728#endif
Fred Drakec9680921999-12-13 16:37:25 +000013729#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013730 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013731#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013732#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013733 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013734#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013735#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013736 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013737#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013738#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013739 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013740#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013741#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013742 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013743#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013744#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013745 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013746#endif
13747#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013748 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013749#endif
13750#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013751 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013752#endif
13753#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013754 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013755#endif
13756#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013757 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013758#endif
13759#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013760 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013761#endif
13762#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013763 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013764#endif
13765#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013766 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013767#endif
13768#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013769 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013770#endif
13771#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013772 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013773#endif
13774#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013775 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013776#endif
13777#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013778 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013779#endif
13780#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013781 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013782#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013783#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013784 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013785#endif
13786#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013787 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013788#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013789#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013790 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013791#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013792#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013793 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013794#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013795#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013796#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013797 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013798#endif
13799#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013800 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013801#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013802#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013803#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013804 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013805#endif
13806#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013807 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013808#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013809#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013810 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013811#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013812#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013813 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013814#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013815#ifdef O_TMPFILE
13816 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13817#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013818#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013819 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013820#endif
13821#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013822 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013823#endif
13824#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013825 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013826#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013827#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013828 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013829#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013830#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013831 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013832#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013833
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013834
Jesus Cea94363612012-06-22 18:32:07 +020013835#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013836 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013837#endif
13838#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013839 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013840#endif
13841
Tim Peters5aa91602002-01-30 05:46:57 +000013842/* MS Windows */
13843#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013844 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013845 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013846#endif
13847#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013848 /* Optimize for short life (keep in memory). */
13849 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013850 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013851#endif
13852#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013853 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013854 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013855#endif
13856#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013857 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013858 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013859#endif
13860#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013861 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013862 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013863#endif
13864
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013865/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013866#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013867 /* Send a SIGIO signal whenever input or output
13868 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013869 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013870#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013871#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013872 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013873 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013874#endif
13875#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013876 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013877 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013878#endif
13879#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013880 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013881 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013882#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013883#ifdef O_NOLINKS
13884 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013885 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013886#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013887#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013888 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013889 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013890#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013891
Victor Stinner8c62be82010-05-06 00:08:46 +000013892 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013893#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013894 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013895#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013896#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013897 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013898#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013899#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013900 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013901#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013902#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013903 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013904#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013905#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013906 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013907#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013908#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013909 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013910#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013911#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013912 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013913#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013914#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013915 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013916#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013917#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013918 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013919#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013920#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013921 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013922#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013923#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013924 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013925#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013926#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013927 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013928#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013929#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013930 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013931#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013932#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013933 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013934#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013935#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013936 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013937#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013938#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013939 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013940#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013941#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013942 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013943#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013944
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013945 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013946#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013947 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013948#endif /* ST_RDONLY */
13949#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013950 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013951#endif /* ST_NOSUID */
13952
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013953 /* GNU extensions */
13954#ifdef ST_NODEV
13955 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13956#endif /* ST_NODEV */
13957#ifdef ST_NOEXEC
13958 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13959#endif /* ST_NOEXEC */
13960#ifdef ST_SYNCHRONOUS
13961 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13962#endif /* ST_SYNCHRONOUS */
13963#ifdef ST_MANDLOCK
13964 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13965#endif /* ST_MANDLOCK */
13966#ifdef ST_WRITE
13967 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13968#endif /* ST_WRITE */
13969#ifdef ST_APPEND
13970 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13971#endif /* ST_APPEND */
13972#ifdef ST_NOATIME
13973 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13974#endif /* ST_NOATIME */
13975#ifdef ST_NODIRATIME
13976 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13977#endif /* ST_NODIRATIME */
13978#ifdef ST_RELATIME
13979 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13980#endif /* ST_RELATIME */
13981
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013982 /* FreeBSD sendfile() constants */
13983#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013984 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013985#endif
13986#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013987 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013988#endif
13989#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013990 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013991#endif
13992
Ross Lagerwall7807c352011-03-17 20:20:30 +020013993 /* constants for posix_fadvise */
13994#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013995 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013996#endif
13997#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013998 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013999#endif
14000#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014001 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014002#endif
14003#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014004 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014005#endif
14006#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014007 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014008#endif
14009#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014010 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014011#endif
14012
14013 /* constants for waitid */
14014#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014015 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14016 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14017 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014018#endif
14019#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014020 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014021#endif
14022#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014023 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014024#endif
14025#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014026 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014027#endif
14028#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014029 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014030#endif
14031#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014032 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014033#endif
14034#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014035 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014036#endif
14037#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014038 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014039#endif
14040
14041 /* constants for lockf */
14042#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014043 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014044#endif
14045#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014046 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014047#endif
14048#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014049 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014050#endif
14051#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014052 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014053#endif
14054
Pablo Galindo4defba32018-01-27 16:16:37 +000014055#ifdef RWF_DSYNC
14056 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14057#endif
14058#ifdef RWF_HIPRI
14059 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14060#endif
14061#ifdef RWF_SYNC
14062 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14063#endif
14064#ifdef RWF_NOWAIT
14065 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14066#endif
14067
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014068/* constants for posix_spawn */
14069#ifdef HAVE_POSIX_SPAWN
14070 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14071 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14072 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14073#endif
14074
pxinwrf2d7ac72019-05-21 18:46:37 +080014075#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014076 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14077 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014078 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014079#endif
14080#ifdef HAVE_SPAWNV
14081 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014082 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014083#endif
14084
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014085#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014086#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014087 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014088#endif
14089#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014090 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014091#endif
14092#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014093 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014094#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014095#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014096 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014097#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014098#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014099 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014100#endif
14101#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014102 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014103#endif
14104#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014105 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014106#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014107#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014108 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014109#endif
14110#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014111 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014112#endif
14113#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014114 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014115#endif
14116#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014117 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014118#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014119#endif
14120
Benjamin Peterson9428d532011-09-14 11:45:52 -040014121#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014122 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14123 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14124 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014125#endif
14126
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014127#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014128 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014129#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014130#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014131 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014132#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014133#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014134 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014135#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014136#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014137 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014138#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014139#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014140 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014141#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014142#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014143 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014144#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014145#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014146 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014147#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014148#if HAVE_DECL_RTLD_MEMBER
14149 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14150#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014151
Victor Stinner9b1f4742016-09-06 16:18:52 -070014152#ifdef HAVE_GETRANDOM_SYSCALL
14153 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14154 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14155#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014156#ifdef HAVE_MEMFD_CREATE
14157 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14158 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14159#ifdef MFD_HUGETLB
14160 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014161#endif
14162#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014163 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014164#endif
14165#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014166 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014167#endif
14168#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014169 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014170#endif
14171#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014172 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014173#endif
14174#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014175 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014176#endif
14177#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014178 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014179#endif
14180#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014181 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014182#endif
14183#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014184 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014185#endif
14186#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014187 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014188#endif
14189#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014190 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014191#endif
14192#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014193 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014194#endif
14195#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014196 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014197#endif
14198#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014199 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014200#endif
14201#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014202 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14203#endif
14204#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014205
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014206#if defined(__APPLE__)
14207 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14208#endif
14209
Steve Dower2438cdf2019-03-29 16:37:16 -070014210#ifdef MS_WINDOWS
14211 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14212 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14213 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14214 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14215 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14216#endif
14217
Victor Stinner8c62be82010-05-06 00:08:46 +000014218 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014219}
14220
14221
Martin v. Löwis1a214512008-06-11 05:26:20 +000014222static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000014223 PyModuleDef_HEAD_INIT,
14224 MODNAME,
14225 posix__doc__,
14226 -1,
14227 posix_methods,
14228 NULL,
14229 NULL,
14230 NULL,
14231 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000014232};
14233
14234
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014235static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014236
14237#ifdef HAVE_FACCESSAT
14238 "HAVE_FACCESSAT",
14239#endif
14240
14241#ifdef HAVE_FCHDIR
14242 "HAVE_FCHDIR",
14243#endif
14244
14245#ifdef HAVE_FCHMOD
14246 "HAVE_FCHMOD",
14247#endif
14248
14249#ifdef HAVE_FCHMODAT
14250 "HAVE_FCHMODAT",
14251#endif
14252
14253#ifdef HAVE_FCHOWN
14254 "HAVE_FCHOWN",
14255#endif
14256
Larry Hastings00964ed2013-08-12 13:49:30 -040014257#ifdef HAVE_FCHOWNAT
14258 "HAVE_FCHOWNAT",
14259#endif
14260
Larry Hastings9cf065c2012-06-22 16:30:09 -070014261#ifdef HAVE_FEXECVE
14262 "HAVE_FEXECVE",
14263#endif
14264
14265#ifdef HAVE_FDOPENDIR
14266 "HAVE_FDOPENDIR",
14267#endif
14268
Georg Brandl306336b2012-06-24 12:55:33 +020014269#ifdef HAVE_FPATHCONF
14270 "HAVE_FPATHCONF",
14271#endif
14272
Larry Hastings9cf065c2012-06-22 16:30:09 -070014273#ifdef HAVE_FSTATAT
14274 "HAVE_FSTATAT",
14275#endif
14276
14277#ifdef HAVE_FSTATVFS
14278 "HAVE_FSTATVFS",
14279#endif
14280
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014281#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014282 "HAVE_FTRUNCATE",
14283#endif
14284
Larry Hastings9cf065c2012-06-22 16:30:09 -070014285#ifdef HAVE_FUTIMENS
14286 "HAVE_FUTIMENS",
14287#endif
14288
14289#ifdef HAVE_FUTIMES
14290 "HAVE_FUTIMES",
14291#endif
14292
14293#ifdef HAVE_FUTIMESAT
14294 "HAVE_FUTIMESAT",
14295#endif
14296
14297#ifdef HAVE_LINKAT
14298 "HAVE_LINKAT",
14299#endif
14300
14301#ifdef HAVE_LCHFLAGS
14302 "HAVE_LCHFLAGS",
14303#endif
14304
14305#ifdef HAVE_LCHMOD
14306 "HAVE_LCHMOD",
14307#endif
14308
14309#ifdef HAVE_LCHOWN
14310 "HAVE_LCHOWN",
14311#endif
14312
14313#ifdef HAVE_LSTAT
14314 "HAVE_LSTAT",
14315#endif
14316
14317#ifdef HAVE_LUTIMES
14318 "HAVE_LUTIMES",
14319#endif
14320
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014321#ifdef HAVE_MEMFD_CREATE
14322 "HAVE_MEMFD_CREATE",
14323#endif
14324
Larry Hastings9cf065c2012-06-22 16:30:09 -070014325#ifdef HAVE_MKDIRAT
14326 "HAVE_MKDIRAT",
14327#endif
14328
14329#ifdef HAVE_MKFIFOAT
14330 "HAVE_MKFIFOAT",
14331#endif
14332
14333#ifdef HAVE_MKNODAT
14334 "HAVE_MKNODAT",
14335#endif
14336
14337#ifdef HAVE_OPENAT
14338 "HAVE_OPENAT",
14339#endif
14340
14341#ifdef HAVE_READLINKAT
14342 "HAVE_READLINKAT",
14343#endif
14344
14345#ifdef HAVE_RENAMEAT
14346 "HAVE_RENAMEAT",
14347#endif
14348
14349#ifdef HAVE_SYMLINKAT
14350 "HAVE_SYMLINKAT",
14351#endif
14352
14353#ifdef HAVE_UNLINKAT
14354 "HAVE_UNLINKAT",
14355#endif
14356
14357#ifdef HAVE_UTIMENSAT
14358 "HAVE_UTIMENSAT",
14359#endif
14360
14361#ifdef MS_WINDOWS
14362 "MS_WINDOWS",
14363#endif
14364
14365 NULL
14366};
14367
14368
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014369PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014370INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014371{
Victor Stinner8c62be82010-05-06 00:08:46 +000014372 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014373 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014374 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014375
Victor Stinner8c62be82010-05-06 00:08:46 +000014376 m = PyModule_Create(&posixmodule);
14377 if (m == NULL)
14378 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014379
Victor Stinner8c62be82010-05-06 00:08:46 +000014380 /* Initialize environ dictionary */
14381 v = convertenviron();
14382 Py_XINCREF(v);
14383 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14384 return NULL;
14385 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014386
Victor Stinner8c62be82010-05-06 00:08:46 +000014387 if (all_ins(m))
14388 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014389
Victor Stinner8c62be82010-05-06 00:08:46 +000014390 if (setup_confname_tables(m))
14391 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014392
Victor Stinner8c62be82010-05-06 00:08:46 +000014393 Py_INCREF(PyExc_OSError);
14394 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014395
Guido van Rossumb3d39562000-01-31 18:41:26 +000014396#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014397 if (posix_putenv_garbage == NULL)
14398 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014399#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014400
Victor Stinner8c62be82010-05-06 00:08:46 +000014401 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014402#if defined(HAVE_WAITID) && !defined(__APPLE__)
14403 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014404 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14405 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014406 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014407 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014408#endif
14409
Christian Heimes25827622013-10-12 01:27:08 +020014410 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014411 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14412 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14413 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014414 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14415 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014416 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014417 }
14418 structseq_new = StatResultType->tp_new;
14419 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014420
Christian Heimes25827622013-10-12 01:27:08 +020014421 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014422 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14423 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014424 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014425 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014426#ifdef NEED_TICKS_PER_SECOND
14427# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014428 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014429# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014430 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014431# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014432 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014433# endif
14434#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014435
William Orr81574b82018-10-01 22:19:56 -070014436#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014437 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014438 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14439 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014440 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014441 }
14442 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014443#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014444
14445 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014446 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14447 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014448 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014449 }
Victor Stinner6036e442015-03-08 01:58:04 +010014450
14451 /* initialize scandir types */
14452 if (PyType_Ready(&ScandirIteratorType) < 0)
14453 return NULL;
14454 if (PyType_Ready(&DirEntryType) < 0)
14455 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014456 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014457#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014458 Py_INCREF((PyObject*) WaitidResultType);
14459 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014460#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014461 Py_INCREF((PyObject*) StatResultType);
14462 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14463 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014464 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014465 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014466
14467#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014468 Py_INCREF(SchedParamType);
14469 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014470#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014471
Larry Hastings605a62d2012-06-24 04:33:36 -070014472 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014473 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14474 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014475 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014476 }
14477 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014478
14479 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014480 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14481 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014482 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014483 }
14484 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014485
Thomas Wouters477c8d52006-05-27 19:21:47 +000014486#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014487 /*
14488 * Step 2 of weak-linking support on Mac OS X.
14489 *
14490 * The code below removes functions that are not available on the
14491 * currently active platform.
14492 *
14493 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014494 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014495 * OSX 10.4.
14496 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014497#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014498 if (fstatvfs == NULL) {
14499 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14500 return NULL;
14501 }
14502 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014503#endif /* HAVE_FSTATVFS */
14504
14505#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014506 if (statvfs == NULL) {
14507 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14508 return NULL;
14509 }
14510 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014511#endif /* HAVE_STATVFS */
14512
14513# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014514 if (lchown == NULL) {
14515 if (PyObject_DelAttrString(m, "lchown") == -1) {
14516 return NULL;
14517 }
14518 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014519#endif /* HAVE_LCHOWN */
14520
14521
14522#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014523
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014524 Py_INCREF(TerminalSizeType);
14525 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014526
Larry Hastings6fe20b32012-04-19 15:07:49 -070014527 billion = PyLong_FromLong(1000000000);
14528 if (!billion)
14529 return NULL;
14530
Larry Hastings9cf065c2012-06-22 16:30:09 -070014531 /* suppress "function not used" warnings */
14532 {
14533 int ignored;
14534 fd_specified("", -1);
14535 follow_symlinks_specified("", 1);
14536 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14537 dir_fd_converter(Py_None, &ignored);
14538 dir_fd_unavailable(Py_None, &ignored);
14539 }
14540
14541 /*
14542 * provide list of locally available functions
14543 * so os.py can populate support_* lists
14544 */
14545 list = PyList_New(0);
14546 if (!list)
14547 return NULL;
14548 for (trace = have_functions; *trace; trace++) {
14549 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14550 if (!unicode)
14551 return NULL;
14552 if (PyList_Append(list, unicode))
14553 return NULL;
14554 Py_DECREF(unicode);
14555 }
14556 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014557
14558 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014559 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014560
14561 initialized = 1;
14562
Victor Stinner8c62be82010-05-06 00:08:46 +000014563 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014564}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014565
14566#ifdef __cplusplus
14567}
14568#endif