blob: f58572b2ceb497c7c257b9b7b3d40451235d3b76 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Antoine Pitrou346cbd32017-05-27 17:50:54 +020028#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010029#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020030#ifndef MS_WINDOWS
31#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010032#else
33#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020034#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000035
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020036/* On android API level 21, 'AT_EACCESS' is not declared although
37 * HAVE_FACCESSAT is defined. */
38#ifdef __ANDROID__
39#undef HAVE_FACCESSAT
40#endif
41
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000042#include <stdio.h> /* needed for ctermid() */
43
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000044#ifdef __cplusplus
45extern "C" {
46#endif
47
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000049"This module provides access to operating system functionality that is\n\
50standardized by the C Standard and the POSIX standard (a thinly\n\
51disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000052corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000054
Ross Lagerwall4d076da2011-03-18 06:56:53 +020055#ifdef HAVE_SYS_UIO_H
56#include <sys/uio.h>
57#endif
58
Christian Heimes75b96182017-09-05 15:53:09 +020059#ifdef HAVE_SYS_SYSMACROS_H
60/* GNU C Library: major(), minor(), makedev() */
61#include <sys/sysmacros.h>
62#endif
63
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000065#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif /* HAVE_SYS_TYPES_H */
67
68#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000069#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000071
Guido van Rossum36bc6801995-06-14 22:54:23 +000072#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000073#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000075
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000077#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000079
Guido van Rossumb6775db1994-08-01 11:34:53 +000080#ifdef HAVE_FCNTL_H
81#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000082#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000083
Guido van Rossuma6535fd2001-10-18 19:44:10 +000084#ifdef HAVE_GRP_H
85#include <grp.h>
86#endif
87
Barry Warsaw5676bd12003-01-07 20:57:09 +000088#ifdef HAVE_SYSEXITS_H
89#include <sysexits.h>
90#endif /* HAVE_SYSEXITS_H */
91
Anthony Baxter8a560de2004-10-13 15:30:56 +000092#ifdef HAVE_SYS_LOADAVG_H
93#include <sys/loadavg.h>
94#endif
95
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000096#ifdef HAVE_SYS_SENDFILE_H
97#include <sys/sendfile.h>
98#endif
99
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500100#ifdef HAVE_SCHED_H
101#include <sched.h>
102#endif
103
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500104#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500105#undef HAVE_SCHED_SETAFFINITY
106#endif
107
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200108#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400109#define USE_XATTRS
110#endif
111
112#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400113#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400114#endif
115
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000116#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
117#ifdef HAVE_SYS_SOCKET_H
118#include <sys/socket.h>
119#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000120#endif
121
Victor Stinner8b905bd2011-10-25 13:34:04 +0200122#ifdef HAVE_DLFCN_H
123#include <dlfcn.h>
124#endif
125
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200126#ifdef __hpux
127#include <sys/mpctl.h>
128#endif
129
130#if defined(__DragonFly__) || \
131 defined(__OpenBSD__) || \
132 defined(__FreeBSD__) || \
133 defined(__NetBSD__) || \
134 defined(__APPLE__)
135#include <sys/sysctl.h>
136#endif
137
Victor Stinner9b1f4742016-09-06 16:18:52 -0700138#ifdef HAVE_LINUX_RANDOM_H
139# include <linux/random.h>
140#endif
141#ifdef HAVE_GETRANDOM_SYSCALL
142# include <sys/syscall.h>
143#endif
144
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100145#if defined(MS_WINDOWS)
146# define TERMSIZE_USE_CONIO
147#elif defined(HAVE_SYS_IOCTL_H)
148# include <sys/ioctl.h>
149# if defined(HAVE_TERMIOS_H)
150# include <termios.h>
151# endif
152# if defined(TIOCGWINSZ)
153# define TERMSIZE_USE_IOCTL
154# endif
155#endif /* MS_WINDOWS */
156
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000158/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#include <process.h>
163#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000165#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000166#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700169#define HAVE_WSPAWNV 1
170#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SYSTEM 1
173#define HAVE_CWAIT 1
174#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000175#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000176#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177/* Unix functions that the configure script doesn't check for */
178#define HAVE_EXECV 1
179#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000181#define HAVE_FORK1 1
182#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#define HAVE_GETEGID 1
184#define HAVE_GETEUID 1
185#define HAVE_GETGID 1
186#define HAVE_GETPPID 1
187#define HAVE_GETUID 1
188#define HAVE_KILL 1
189#define HAVE_OPENDIR 1
190#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000193#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000194#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000195#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000196
Victor Stinnera2f7c002012-02-08 03:36:25 +0100197
Larry Hastings61272b72014-01-07 12:41:53 -0800198/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000199# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800200module os
Larry Hastings61272b72014-01-07 12:41:53 -0800201[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000202/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100203
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000205
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000206#if defined(__sgi)&&_COMPILER_VERSION>=700
207/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
208 (default) */
209extern char *ctermid_r(char *);
210#endif
211
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000212#ifndef HAVE_UNISTD_H
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000213#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000216extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chdir(char *);
220extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int chdir(const char *);
223extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000224#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000226/*#ifdef HAVE_FCHMOD
227extern int fchmod(int, mode_t);
228#endif*/
229/*#ifdef HAVE_LCHMOD
230extern int lchmod(const char *, mode_t);
231#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000232extern int chown(const char *, uid_t, gid_t);
233extern char *getcwd(char *, int);
234extern char *strerror(int);
235extern int link(const char *, const char *);
236extern int rename(const char *, const char *);
237extern int stat(const char *, struct stat *);
238extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000241#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000243extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000246
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000247#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#ifdef HAVE_UTIME_H
250#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000251#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000253#ifdef HAVE_SYS_UTIME_H
254#include <sys/utime.h>
255#define HAVE_UTIME_H /* pretend we do for the rest of this file */
256#endif /* HAVE_SYS_UTIME_H */
257
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#ifdef HAVE_SYS_TIMES_H
259#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000260#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261
262#ifdef HAVE_SYS_PARAM_H
263#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
266#ifdef HAVE_SYS_UTSNAME_H
267#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000268#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) strlen((dirent)->d_name)
273#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000274#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#include <direct.h>
276#define NAMLEN(dirent) strlen((dirent)->d_name)
277#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000280#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#endif
287#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000289#endif
290#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000292#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
296#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298#endif
299#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000302#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100305#ifndef IO_REPARSE_TAG_MOUNT_POINT
306#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
307#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000309#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000311#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000312#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000313#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
314#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000315static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000316#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#if defined(PATH_MAX) && PATH_MAX > 1024
321#define MAXPATHLEN PATH_MAX
322#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#endif /* MAXPATHLEN */
326
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000327#ifdef UNION_WAIT
328/* Emulate some macros on systems that have a union instead of macros */
329
330#ifndef WIFEXITED
331#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
332#endif
333
334#ifndef WEXITSTATUS
335#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
336#endif
337
338#ifndef WTERMSIG
339#define WTERMSIG(u_wait) ((u_wait).w_termsig)
340#endif
341
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000342#define WAIT_TYPE union wait
343#define WAIT_STATUS_INT(s) (s.w_status)
344
345#else /* !UNION_WAIT */
346#define WAIT_TYPE int
347#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000348#endif /* UNION_WAIT */
349
Greg Wardb48bc172000-03-01 21:51:56 +0000350/* Don't use the "_r" form if we don't need it (also, won't have a
351 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200352#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000353#define USE_CTERMID_R
354#endif
355
Fred Drake699f3522000-06-29 21:12:41 +0000356/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000357#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000358#undef FSTAT
359#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200360#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000361# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700362# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200363# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800364# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000365#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define FSTAT fstat
369# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000370#endif
371
Tim Peters11b23062003-04-23 02:39:17 +0000372#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000373#include <sys/mkdev.h>
374#else
375#if defined(MAJOR_IN_SYSMACROS)
376#include <sys/sysmacros.h>
377#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000378#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
379#include <sys/mkdev.h>
380#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#endif
Fred Drake699f3522000-06-29 21:12:41 +0000382
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200383#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100384#define INITFUNC PyInit_nt
385#define MODNAME "nt"
386#else
387#define INITFUNC PyInit_posix
388#define MODNAME "posix"
389#endif
390
jcea6c51d512018-01-28 14:00:08 +0100391#if defined(__sun)
392/* Something to implement in autoconf, not present in autoconf 2.69 */
393#define HAVE_STRUCT_STAT_ST_FSTYPE 1
394#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200395
Gregory P. Smithefcf08d2018-12-30 22:14:33 -0800396#ifdef _Py_MEMORY_SANITIZER
397# include <sanitizer/msan_interface.h>
398#endif
399
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200400#ifdef HAVE_FORK
401static void
402run_at_forkers(PyObject *lst, int reverse)
403{
404 Py_ssize_t i;
405 PyObject *cpy;
406
407 if (lst != NULL) {
408 assert(PyList_CheckExact(lst));
409
410 /* Use a list copy in case register_at_fork() is called from
411 * one of the callbacks.
412 */
413 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
414 if (cpy == NULL)
415 PyErr_WriteUnraisable(lst);
416 else {
417 if (reverse)
418 PyList_Reverse(cpy);
419 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
420 PyObject *func, *res;
421 func = PyList_GET_ITEM(cpy, i);
422 res = PyObject_CallObject(func, NULL);
423 if (res == NULL)
424 PyErr_WriteUnraisable(func);
425 else
426 Py_DECREF(res);
427 }
428 Py_DECREF(cpy);
429 }
430 }
431}
432
433void
434PyOS_BeforeFork(void)
435{
436 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
437
438 _PyImport_AcquireLock();
439}
440
441void
442PyOS_AfterFork_Parent(void)
443{
444 if (_PyImport_ReleaseLock() <= 0)
445 Py_FatalError("failed releasing import lock after fork");
446
447 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
448}
449
450void
451PyOS_AfterFork_Child(void)
452{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200453 _PyGILState_Reinit();
454 PyEval_ReInitThreads();
455 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200456 _PySignal_AfterFork();
457
458 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
459}
460
461static int
462register_at_forker(PyObject **lst, PyObject *func)
463{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700464 if (func == NULL) /* nothing to register? do nothing. */
465 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200466 if (*lst == NULL) {
467 *lst = PyList_New(0);
468 if (*lst == NULL)
469 return -1;
470 }
471 return PyList_Append(*lst, func);
472}
473#endif
474
475/* Legacy wrapper */
476void
477PyOS_AfterFork(void)
478{
479#ifdef HAVE_FORK
480 PyOS_AfterFork_Child();
481#endif
482}
483
484
Victor Stinner6036e442015-03-08 01:58:04 +0100485#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200486/* defined in fileutils.c */
487PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
488PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
489 ULONG, struct _Py_stat_struct *);
490#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700491
492#ifdef MS_WINDOWS
493static int
494win32_warn_bytes_api()
495{
496 return PyErr_WarnEx(PyExc_DeprecationWarning,
497 "The Windows bytes API has been deprecated, "
498 "use Unicode filenames instead",
499 1);
500}
501#endif
502
503
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200504#ifndef MS_WINDOWS
505PyObject *
506_PyLong_FromUid(uid_t uid)
507{
508 if (uid == (uid_t)-1)
509 return PyLong_FromLong(-1);
510 return PyLong_FromUnsignedLong(uid);
511}
512
513PyObject *
514_PyLong_FromGid(gid_t gid)
515{
516 if (gid == (gid_t)-1)
517 return PyLong_FromLong(-1);
518 return PyLong_FromUnsignedLong(gid);
519}
520
521int
522_Py_Uid_Converter(PyObject *obj, void *p)
523{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 uid_t uid;
525 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200527 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 unsigned long uresult;
529
530 index = PyNumber_Index(obj);
531 if (index == NULL) {
532 PyErr_Format(PyExc_TypeError,
533 "uid should be integer, not %.200s",
534 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200535 return 0;
536 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537
538 /*
539 * Handling uid_t is complicated for two reasons:
540 * * Although uid_t is (always?) unsigned, it still
541 * accepts -1.
542 * * We don't know its size in advance--it may be
543 * bigger than an int, or it may be smaller than
544 * a long.
545 *
546 * So a bit of defensive programming is in order.
547 * Start with interpreting the value passed
548 * in as a signed long and see if it works.
549 */
550
551 result = PyLong_AsLongAndOverflow(index, &overflow);
552
553 if (!overflow) {
554 uid = (uid_t)result;
555
556 if (result == -1) {
557 if (PyErr_Occurred())
558 goto fail;
559 /* It's a legitimate -1, we're done. */
560 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200561 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700562
563 /* Any other negative number is disallowed. */
564 if (result < 0)
565 goto underflow;
566
567 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569 (long)uid != result)
570 goto underflow;
571 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200572 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700573
574 if (overflow < 0)
575 goto underflow;
576
577 /*
578 * Okay, the value overflowed a signed long. If it
579 * fits in an *unsigned* long, it may still be okay,
580 * as uid_t may be unsigned long on this platform.
581 */
582 uresult = PyLong_AsUnsignedLong(index);
583 if (PyErr_Occurred()) {
584 if (PyErr_ExceptionMatches(PyExc_OverflowError))
585 goto overflow;
586 goto fail;
587 }
588
589 uid = (uid_t)uresult;
590
591 /*
592 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
593 * but this value would get interpreted as (uid_t)-1 by chown
594 * and its siblings. That's not what the user meant! So we
595 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100596 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700597 */
598 if (uid == (uid_t)-1)
599 goto overflow;
600
601 /* Ensure the value wasn't truncated. */
602 if (sizeof(uid_t) < sizeof(long) &&
603 (unsigned long)uid != uresult)
604 goto overflow;
605 /* fallthrough */
606
607success:
608 Py_DECREF(index);
609 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 return 1;
611
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700612underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614 "uid is less than minimum");
615 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700617overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700619 "uid is greater than maximum");
620 /* fallthrough */
621
622fail:
623 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 return 0;
625}
626
627int
628_Py_Gid_Converter(PyObject *obj, void *p)
629{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700630 gid_t gid;
631 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200633 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634 unsigned long uresult;
635
636 index = PyNumber_Index(obj);
637 if (index == NULL) {
638 PyErr_Format(PyExc_TypeError,
639 "gid should be integer, not %.200s",
640 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200641 return 0;
642 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700643
644 /*
645 * Handling gid_t is complicated for two reasons:
646 * * Although gid_t is (always?) unsigned, it still
647 * accepts -1.
648 * * We don't know its size in advance--it may be
649 * bigger than an int, or it may be smaller than
650 * a long.
651 *
652 * So a bit of defensive programming is in order.
653 * Start with interpreting the value passed
654 * in as a signed long and see if it works.
655 */
656
657 result = PyLong_AsLongAndOverflow(index, &overflow);
658
659 if (!overflow) {
660 gid = (gid_t)result;
661
662 if (result == -1) {
663 if (PyErr_Occurred())
664 goto fail;
665 /* It's a legitimate -1, we're done. */
666 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200667 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700668
669 /* Any other negative number is disallowed. */
670 if (result < 0) {
671 goto underflow;
672 }
673
674 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200675 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700676 (long)gid != result)
677 goto underflow;
678 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680
681 if (overflow < 0)
682 goto underflow;
683
684 /*
685 * Okay, the value overflowed a signed long. If it
686 * fits in an *unsigned* long, it may still be okay,
687 * as gid_t may be unsigned long on this platform.
688 */
689 uresult = PyLong_AsUnsignedLong(index);
690 if (PyErr_Occurred()) {
691 if (PyErr_ExceptionMatches(PyExc_OverflowError))
692 goto overflow;
693 goto fail;
694 }
695
696 gid = (gid_t)uresult;
697
698 /*
699 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
700 * but this value would get interpreted as (gid_t)-1 by chown
701 * and its siblings. That's not what the user meant! So we
702 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100703 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700704 */
705 if (gid == (gid_t)-1)
706 goto overflow;
707
708 /* Ensure the value wasn't truncated. */
709 if (sizeof(gid_t) < sizeof(long) &&
710 (unsigned long)gid != uresult)
711 goto overflow;
712 /* fallthrough */
713
714success:
715 Py_DECREF(index);
716 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200717 return 1;
718
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700719underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200720 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700721 "gid is less than minimum");
722 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200723
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700724overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200725 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700726 "gid is greater than maximum");
727 /* fallthrough */
728
729fail:
730 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200731 return 0;
732}
733#endif /* MS_WINDOWS */
734
735
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700736#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800737
738
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200739#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
740static int
741_Py_Dev_Converter(PyObject *obj, void *p)
742{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200744 if (PyErr_Occurred())
745 return 0;
746 return 1;
747}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800748#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200749
750
Larry Hastings9cf065c2012-06-22 16:30:09 -0700751#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400752/*
753 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
754 * without the int cast, the value gets interpreted as uint (4291925331),
755 * which doesn't play nicely with all the initializer lines in this file that
756 * look like this:
757 * int dir_fd = DEFAULT_DIR_FD;
758 */
759#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760#else
761#define DEFAULT_DIR_FD (-100)
762#endif
763
764static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300765_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200766{
767 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700768 long long_value;
769
770 PyObject *index = PyNumber_Index(o);
771 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700772 return 0;
773 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700774
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300775 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700776 long_value = PyLong_AsLongAndOverflow(index, &overflow);
777 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300778 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200779 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700781 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700782 return 0;
783 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200784 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700785 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700786 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700787 return 0;
788 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700789
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 *p = (int)long_value;
791 return 1;
792}
793
794static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200795dir_fd_converter(PyObject *o, void *p)
796{
797 if (o == Py_None) {
798 *(int *)p = DEFAULT_DIR_FD;
799 return 1;
800 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300801 else if (PyIndex_Check(o)) {
802 return _fd_converter(o, (int *)p);
803 }
804 else {
805 PyErr_Format(PyExc_TypeError,
806 "argument should be integer or None, not %.200s",
807 Py_TYPE(o)->tp_name);
808 return 0;
809 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700810}
811
812
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813/*
814 * A PyArg_ParseTuple "converter" function
815 * that handles filesystem paths in the manner
816 * preferred by the os module.
817 *
818 * path_converter accepts (Unicode) strings and their
819 * subclasses, and bytes and their subclasses. What
820 * it does with the argument depends on the platform:
821 *
822 * * On Windows, if we get a (Unicode) string we
823 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700824 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700825 *
826 * * On all other platforms, strings are encoded
827 * to bytes using PyUnicode_FSConverter, then we
828 * extract the char * from the bytes object and
829 * return that.
830 *
831 * path_converter also optionally accepts signed
832 * integers (representing open file descriptors) instead
833 * of path strings.
834 *
835 * Input fields:
836 * path.nullable
837 * If nonzero, the path is permitted to be None.
838 * path.allow_fd
839 * If nonzero, the path is permitted to be a file handle
840 * (a signed int) instead of a string.
841 * path.function_name
842 * If non-NULL, path_converter will use that as the name
843 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700844 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700845 * path.argument_name
846 * If non-NULL, path_converter will use that as the name
847 * of the parameter in error messages.
848 * (If path.argument_name is NULL it uses "path".)
849 *
850 * Output fields:
851 * path.wide
852 * Points to the path if it was expressed as Unicode
853 * and was not encoded. (Only used on Windows.)
854 * path.narrow
855 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700856 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000857 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700858 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859 * path.fd
860 * Contains a file descriptor if path.accept_fd was true
861 * and the caller provided a signed integer instead of any
862 * sort of string.
863 *
864 * WARNING: if your "path" parameter is optional, and is
865 * unspecified, path_converter will never get called.
866 * So if you set allow_fd, you *MUST* initialize path.fd = -1
867 * yourself!
868 * path.length
869 * The length of the path in characters, if specified as
870 * a string.
871 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800872 * The original object passed in (if get a PathLike object,
873 * the result of PyOS_FSPath() is treated as the original object).
874 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 * path.cleanup
876 * For internal use only. May point to a temporary object.
877 * (Pay no attention to the man behind the curtain.)
878 *
879 * At most one of path.wide or path.narrow will be non-NULL.
880 * If path was None and path.nullable was set,
881 * or if path was an integer and path.allow_fd was set,
882 * both path.wide and path.narrow will be NULL
883 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200884 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700885 * path_converter takes care to not write to the path_t
886 * unless it's successful. However it must reset the
887 * "cleanup" field each time it's called.
888 *
889 * Use as follows:
890 * path_t path;
891 * memset(&path, 0, sizeof(path));
892 * PyArg_ParseTuple(args, "O&", path_converter, &path);
893 * // ... use values from path ...
894 * path_cleanup(&path);
895 *
896 * (Note that if PyArg_Parse fails you don't need to call
897 * path_cleanup(). However it is safe to do so.)
898 */
899typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100900 const char *function_name;
901 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700902 int nullable;
903 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300904 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700905#ifdef MS_WINDOWS
906 BOOL narrow;
907#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300908 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700909#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700910 int fd;
911 Py_ssize_t length;
912 PyObject *object;
913 PyObject *cleanup;
914} path_t;
915
Steve Dowercc16be82016-09-08 10:35:16 -0700916#ifdef MS_WINDOWS
917#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
918 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
919#else
Larry Hastings2f936352014-08-05 14:04:04 +1000920#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
921 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700922#endif
Larry Hastings31826802013-10-19 00:09:25 -0700923
Larry Hastings9cf065c2012-06-22 16:30:09 -0700924static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800925path_cleanup(path_t *path)
926{
927 Py_CLEAR(path->object);
928 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929}
930
931static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300932path_converter(PyObject *o, void *p)
933{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800935 PyObject *bytes = NULL;
936 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700937 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300938 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700939#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800940 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700941 const wchar_t *wide;
942#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943
944#define FORMAT_EXCEPTION(exc, fmt) \
945 PyErr_Format(exc, "%s%s" fmt, \
946 path->function_name ? path->function_name : "", \
947 path->function_name ? ": " : "", \
948 path->argument_name ? path->argument_name : "path")
949
950 /* Py_CLEANUP_SUPPORTED support */
951 if (o == NULL) {
952 path_cleanup(path);
953 return 1;
954 }
955
Brett Cannon3f9183b2016-08-26 14:44:48 -0700956 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800957 path->object = path->cleanup = NULL;
958 /* path->object owns a reference to the original object */
959 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300961 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700963#ifdef MS_WINDOWS
964 path->narrow = FALSE;
965#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700967#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800969 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700970 }
971
Brett Cannon3f9183b2016-08-26 14:44:48 -0700972 /* Only call this here so that we don't treat the return value of
973 os.fspath() as an fd or buffer. */
974 is_index = path->allow_fd && PyIndex_Check(o);
975 is_buffer = PyObject_CheckBuffer(o);
976 is_bytes = PyBytes_Check(o);
977 is_unicode = PyUnicode_Check(o);
978
979 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
980 /* Inline PyOS_FSPath() for better error messages. */
981 _Py_IDENTIFIER(__fspath__);
982 PyObject *func = NULL;
983
984 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
985 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800986 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800988 /* still owns a reference to the original object */
989 Py_DECREF(o);
990 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700991 Py_DECREF(func);
992 if (NULL == o) {
993 goto error_exit;
994 }
995 else if (PyUnicode_Check(o)) {
996 is_unicode = 1;
997 }
998 else if (PyBytes_Check(o)) {
999 is_bytes = 1;
1000 }
1001 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001002 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001003 }
1004 }
1005
1006 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001008 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001009 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011 }
Victor Stinner59799a82013-11-13 14:17:30 +01001012 if (length > 32767) {
1013 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001016 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001017 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001019 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001020
1021 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001022 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001023 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001024 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001026 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001027 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001028 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001029#endif
1030 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001031 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001032 bytes = o;
1033 Py_INCREF(bytes);
1034 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001035 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001036 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001037 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001038 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1039 "%s%s%s should be %s, not %.200s",
1040 path->function_name ? path->function_name : "",
1041 path->function_name ? ": " : "",
1042 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1044 "integer or None" :
1045 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1046 path->nullable ? "string, bytes, os.PathLike or None" :
1047 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001050 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001051 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001053 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 }
1055 }
Steve Dowercc16be82016-09-08 10:35:16 -07001056 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001057 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001058 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001059 }
1060 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001061#ifdef MS_WINDOWS
1062 path->narrow = FALSE;
1063#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001064 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001065#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001066 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001067 }
1068 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001069 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001070 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1071 path->function_name ? path->function_name : "",
1072 path->function_name ? ": " : "",
1073 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001074 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1075 "integer or None" :
1076 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1077 path->nullable ? "string, bytes, os.PathLike or None" :
1078 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001079 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001080 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 }
1082
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001085 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001086 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001087 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001088 }
1089
Steve Dowercc16be82016-09-08 10:35:16 -07001090#ifdef MS_WINDOWS
1091 wo = PyUnicode_DecodeFSDefaultAndSize(
1092 narrow,
1093 length
1094 );
1095 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001096 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001097 }
1098
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001100 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001102 }
1103 if (length > 32767) {
1104 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 if (wcslen(wide) != length) {
1108 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001110 }
1111 path->wide = wide;
1112 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001113 path->cleanup = wo;
1114 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001115#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001116 path->wide = NULL;
1117 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001118 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 /* Still a reference owned by path->object, don't have to
1120 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001122 }
1123 else {
1124 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001125 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001126#endif
1127 path->fd = -1;
1128
1129 success_exit:
1130 path->length = length;
1131 path->object = o;
1132 return Py_CLEANUP_SUPPORTED;
1133
1134 error_exit:
1135 Py_XDECREF(o);
1136 Py_XDECREF(bytes);
1137#ifdef MS_WINDOWS
1138 Py_XDECREF(wo);
1139#endif
1140 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141}
1142
1143static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001144argument_unavailable_error(const char *function_name, const char *argument_name)
1145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 PyErr_Format(PyExc_NotImplementedError,
1147 "%s%s%s unavailable on this platform",
1148 (function_name != NULL) ? function_name : "",
1149 (function_name != NULL) ? ": ": "",
1150 argument_name);
1151}
1152
1153static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001154dir_fd_unavailable(PyObject *o, void *p)
1155{
1156 int dir_fd;
1157 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001158 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001159 if (dir_fd != DEFAULT_DIR_FD) {
1160 argument_unavailable_error(NULL, "dir_fd");
1161 return 0;
1162 }
1163 *(int *)p = dir_fd;
1164 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165}
1166
1167static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001168fd_specified(const char *function_name, int fd)
1169{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 if (fd == -1)
1171 return 0;
1172
1173 argument_unavailable_error(function_name, "fd");
1174 return 1;
1175}
1176
1177static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001178follow_symlinks_specified(const char *function_name, int follow_symlinks)
1179{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001180 if (follow_symlinks)
1181 return 0;
1182
1183 argument_unavailable_error(function_name, "follow_symlinks");
1184 return 1;
1185}
1186
1187static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001188path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1189{
Steve Dowercc16be82016-09-08 10:35:16 -07001190 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1191#ifndef MS_WINDOWS
1192 && !path->narrow
1193#endif
1194 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001195 PyErr_Format(PyExc_ValueError,
1196 "%s: can't specify dir_fd without matching path",
1197 function_name);
1198 return 1;
1199 }
1200 return 0;
1201}
1202
1203static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001204dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1205{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1207 PyErr_Format(PyExc_ValueError,
1208 "%s: can't specify both dir_fd and fd",
1209 function_name);
1210 return 1;
1211 }
1212 return 0;
1213}
1214
1215static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001216fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1217 int follow_symlinks)
1218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 if ((fd > 0) && (!follow_symlinks)) {
1220 PyErr_Format(PyExc_ValueError,
1221 "%s: cannot use fd and follow_symlinks together",
1222 function_name);
1223 return 1;
1224 }
1225 return 0;
1226}
1227
1228static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001229dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1230 int follow_symlinks)
1231{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001232 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1233 PyErr_Format(PyExc_ValueError,
1234 "%s: cannot use dir_fd and follow_symlinks together",
1235 function_name);
1236 return 1;
1237 }
1238 return 0;
1239}
1240
Larry Hastings2f936352014-08-05 14:04:04 +10001241#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001242 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001243#else
Larry Hastings2f936352014-08-05 14:04:04 +10001244 typedef off_t Py_off_t;
1245#endif
1246
1247static int
1248Py_off_t_converter(PyObject *arg, void *addr)
1249{
1250#ifdef HAVE_LARGEFILE_SUPPORT
1251 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1252#else
1253 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001254#endif
1255 if (PyErr_Occurred())
1256 return 0;
1257 return 1;
1258}
Larry Hastings2f936352014-08-05 14:04:04 +10001259
1260static PyObject *
1261PyLong_FromPy_off_t(Py_off_t offset)
1262{
1263#ifdef HAVE_LARGEFILE_SUPPORT
1264 return PyLong_FromLongLong(offset);
1265#else
1266 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001267#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001268}
1269
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001270#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001271
1272static int
Brian Curtind25aef52011-06-13 15:16:04 -05001273win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274{
Martin Panter70214ad2016-08-04 02:38:59 +00001275 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1276 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001277 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278
1279 if (0 == DeviceIoControl(
1280 reparse_point_handle,
1281 FSCTL_GET_REPARSE_POINT,
1282 NULL, 0, /* in buffer */
1283 target_buffer, sizeof(target_buffer),
1284 &n_bytes_returned,
1285 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001286 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001287
1288 if (reparse_tag)
1289 *reparse_tag = rdb->ReparseTag;
1290
Brian Curtind25aef52011-06-13 15:16:04 -05001291 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001292}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001293
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001294#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001296/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001297#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001298/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001299** environ directly, we must obtain it with _NSGetEnviron(). See also
1300** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001301*/
1302#include <crt_externs.h>
1303static char **environ;
1304#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001306#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307
Barry Warsaw53699e91996-12-10 23:23:01 +00001308static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001309convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310{
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001314#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001315 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001316#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001317
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 d = PyDict_New();
1319 if (d == NULL)
1320 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001321#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 if (environ == NULL)
1323 environ = *_NSGetEnviron();
1324#endif
1325#ifdef MS_WINDOWS
1326 /* _wenviron must be initialized in this way if the program is started
1327 through main() instead of wmain(). */
1328 _wgetenv(L"");
1329 if (_wenviron == NULL)
1330 return d;
1331 /* This part ignores errors */
1332 for (e = _wenviron; *e != NULL; e++) {
1333 PyObject *k;
1334 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001335 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001336 if (p == NULL)
1337 continue;
1338 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1339 if (k == NULL) {
1340 PyErr_Clear();
1341 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001342 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1344 if (v == NULL) {
1345 PyErr_Clear();
1346 Py_DECREF(k);
1347 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001348 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 if (PyDict_GetItem(d, k) == NULL) {
1350 if (PyDict_SetItem(d, k, v) != 0)
1351 PyErr_Clear();
1352 }
1353 Py_DECREF(k);
1354 Py_DECREF(v);
1355 }
1356#else
1357 if (environ == NULL)
1358 return d;
1359 /* This part ignores errors */
1360 for (e = environ; *e != NULL; e++) {
1361 PyObject *k;
1362 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001363 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 if (p == NULL)
1365 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001366 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001367 if (k == NULL) {
1368 PyErr_Clear();
1369 continue;
1370 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001371 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 if (v == NULL) {
1373 PyErr_Clear();
1374 Py_DECREF(k);
1375 continue;
1376 }
1377 if (PyDict_GetItem(d, k) == NULL) {
1378 if (PyDict_SetItem(d, k, v) != 0)
1379 PyErr_Clear();
1380 }
1381 Py_DECREF(k);
1382 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001383 }
1384#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001386}
1387
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388/* Set a POSIX-specific error from errno, and return NULL */
1389
Barry Warsawd58d7641998-07-23 16:14:40 +00001390static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001391posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001392{
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001394}
Mark Hammondef8b6542001-05-13 08:04:26 +00001395
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001396#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001397static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001398win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001399{
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 /* XXX We should pass the function name along in the future.
1401 (winreg.c also wants to pass the function name.)
1402 This would however require an additional param to the
1403 Windows error object, which is non-trivial.
1404 */
1405 errno = GetLastError();
1406 if (filename)
1407 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1408 else
1409 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001410}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001411
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001412static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001413win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001414{
1415 /* XXX - see win32_error for comments on 'function' */
1416 errno = GetLastError();
1417 if (filename)
1418 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001419 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001420 errno,
1421 filename);
1422 else
1423 return PyErr_SetFromWindowsErr(errno);
1424}
1425
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001426#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427
Larry Hastings9cf065c2012-06-22 16:30:09 -07001428static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001429posix_path_object_error(PyObject *path)
1430{
1431 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1432}
1433
1434static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001435path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436{
1437#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001438 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1439 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001440#else
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001441 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001442#endif
1443}
1444
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001445static PyObject *
1446path_object_error2(PyObject *path, PyObject *path2)
1447{
1448#ifdef MS_WINDOWS
1449 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1450 PyExc_OSError, 0, path, path2);
1451#else
1452 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1453#endif
1454}
1455
1456static PyObject *
1457path_error(path_t *path)
1458{
1459 return path_object_error(path->object);
1460}
Larry Hastings31826802013-10-19 00:09:25 -07001461
Larry Hastingsb0827312014-02-09 22:05:19 -08001462static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001463posix_path_error(path_t *path)
1464{
1465 return posix_path_object_error(path->object);
1466}
1467
1468static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001469path_error2(path_t *path, path_t *path2)
1470{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001471 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001472}
1473
1474
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001475/* POSIX generic methods */
1476
Larry Hastings2f936352014-08-05 14:04:04 +10001477static int
1478fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001479{
Victor Stinner8c62be82010-05-06 00:08:46 +00001480 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001481 int *pointer = (int *)p;
1482 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001483 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001484 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001485 *pointer = fd;
1486 return 1;
1487}
1488
1489static PyObject *
1490posix_fildes_fd(int fd, int (*func)(int))
1491{
1492 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001493 int async_err = 0;
1494
1495 do {
1496 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001497 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001498 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001499 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001500 Py_END_ALLOW_THREADS
1501 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1502 if (res != 0)
1503 return (!async_err) ? posix_error() : NULL;
1504 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001505}
Guido van Rossum21142a01999-01-08 21:05:37 +00001506
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001507
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001508#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001509/* This is a reimplementation of the C library's chdir function,
1510 but one that produces Win32 errors instead of DOS error codes.
1511 chdir is essentially a wrapper around SetCurrentDirectory; however,
1512 it also needs to set "magic" environment variables indicating
1513 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001514static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515win32_wchdir(LPCWSTR path)
1516{
Victor Stinnered537822015-12-13 21:40:26 +01001517 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 int result;
1519 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001520
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 if(!SetCurrentDirectoryW(path))
1522 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001523 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 if (!result)
1525 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001526 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001527 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001528 if (!new_path) {
1529 SetLastError(ERROR_OUTOFMEMORY);
1530 return FALSE;
1531 }
1532 result = GetCurrentDirectoryW(result, new_path);
1533 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001534 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001535 return FALSE;
1536 }
1537 }
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001538 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1539 wcsncmp(new_path, L"//", 2) == 0);
1540 if (!is_unc_like_path) {
1541 env[1] = new_path[0];
1542 result = SetEnvironmentVariableW(env, new_path);
1543 }
Victor Stinnered537822015-12-13 21:40:26 +01001544 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001545 PyMem_RawFree(new_path);
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001546 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547}
1548#endif
1549
Martin v. Löwis14694662006-02-03 12:54:16 +00001550#ifdef MS_WINDOWS
1551/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1552 - time stamps are restricted to second resolution
1553 - file modification times suffer from forth-and-back conversions between
1554 UTC and local time
1555 Therefore, we implement our own stat, based on the Win32 API directly.
1556*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001557#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001558#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001559
Victor Stinner6036e442015-03-08 01:58:04 +01001560static void
Steve Dowercc16be82016-09-08 10:35:16 -07001561find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1562 BY_HANDLE_FILE_INFORMATION *info,
1563 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001564{
1565 memset(info, 0, sizeof(*info));
1566 info->dwFileAttributes = pFileData->dwFileAttributes;
1567 info->ftCreationTime = pFileData->ftCreationTime;
1568 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1569 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1570 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1571 info->nFileSizeLow = pFileData->nFileSizeLow;
1572/* info->nNumberOfLinks = 1; */
1573 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1574 *reparse_tag = pFileData->dwReserved0;
1575 else
1576 *reparse_tag = 0;
1577}
1578
Guido van Rossumd8faa362007-04-27 19:54:29 +00001579static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001580attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001581{
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 HANDLE hFindFile;
1583 WIN32_FIND_DATAW FileData;
1584 hFindFile = FindFirstFileW(pszFile, &FileData);
1585 if (hFindFile == INVALID_HANDLE_VALUE)
1586 return FALSE;
1587 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001588 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001589 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001590}
1591
Brian Curtind25aef52011-06-13 15:16:04 -05001592static BOOL
1593get_target_path(HANDLE hdl, wchar_t **target_path)
1594{
1595 int buf_size, result_length;
1596 wchar_t *buf;
1597
1598 /* We have a good handle to the target, use it to determine
1599 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001600 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1601 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001602 if(!buf_size)
1603 return FALSE;
1604
Victor Stinnerc36674a2016-03-16 14:30:16 +01001605 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001606 if (!buf) {
1607 SetLastError(ERROR_OUTOFMEMORY);
1608 return FALSE;
1609 }
1610
Steve Dower2ea51c92015-03-20 21:49:12 -07001611 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001612 buf, buf_size, VOLUME_NAME_DOS);
1613
1614 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001615 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001616 return FALSE;
1617 }
1618
1619 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001620 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001621 return FALSE;
1622 }
1623
1624 buf[result_length] = 0;
1625
1626 *target_path = buf;
1627 return TRUE;
1628}
1629
1630static int
Steve Dowercc16be82016-09-08 10:35:16 -07001631win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001632 BOOL traverse)
1633{
Victor Stinner26de69d2011-06-17 15:15:38 +02001634 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001635 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001637 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001638 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001639 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001640
Steve Dowercc16be82016-09-08 10:35:16 -07001641 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001642 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001643 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001644 0, /* share mode */
1645 NULL, /* security attributes */
1646 OPEN_EXISTING,
1647 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001648 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1649 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001650 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001651 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1652 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001653 NULL);
1654
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001655 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001656 /* Either the target doesn't exist, or we don't have access to
1657 get a handle to it. If the former, we need to return an error.
1658 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001659 DWORD lastError = GetLastError();
1660 if (lastError != ERROR_ACCESS_DENIED &&
1661 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001662 return -1;
1663 /* Could not get attributes on open file. Fall back to
1664 reading the directory. */
1665 if (!attributes_from_dir(path, &info, &reparse_tag))
1666 /* Very strange. This should not fail now */
1667 return -1;
1668 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1669 if (traverse) {
1670 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001671 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001672 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001673 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001674 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 } else {
1676 if (!GetFileInformationByHandle(hFile, &info)) {
1677 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001678 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 }
1680 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001681 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1682 return -1;
1683
1684 /* Close the outer open file handle now that we're about to
1685 reopen it with different flags. */
1686 if (!CloseHandle(hFile))
1687 return -1;
1688
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001689 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001690 /* In order to call GetFinalPathNameByHandle we need to open
1691 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001692 hFile2 = CreateFileW(
1693 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1694 NULL, OPEN_EXISTING,
1695 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1696 NULL);
1697 if (hFile2 == INVALID_HANDLE_VALUE)
1698 return -1;
1699
1700 if (!get_target_path(hFile2, &target_path))
1701 return -1;
1702
Steve Dowercc16be82016-09-08 10:35:16 -07001703 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001704 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001705 return code;
1706 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001707 } else
1708 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001709 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001710 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001711
1712 /* Set S_IEXEC if it is an .exe, .bat, ... */
1713 dot = wcsrchr(path, '.');
1714 if (dot) {
1715 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1716 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1717 result->st_mode |= 0111;
1718 }
1719 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720}
1721
1722static int
Steve Dowercc16be82016-09-08 10:35:16 -07001723win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001724{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001725 /* Protocol violation: we explicitly clear errno, instead of
1726 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001727 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001728 errno = 0;
1729 return code;
1730}
Brian Curtind25aef52011-06-13 15:16:04 -05001731/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001732
1733 In Posix, stat automatically traverses symlinks and returns the stat
1734 structure for the target. In Windows, the equivalent GetFileAttributes by
1735 default does not traverse symlinks and instead returns attributes for
1736 the symlink.
1737
1738 Therefore, win32_lstat will get the attributes traditionally, and
1739 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001740 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001741
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001742static int
Steve Dowercc16be82016-09-08 10:35:16 -07001743win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001744{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001745 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001746}
1747
Victor Stinner8c62be82010-05-06 00:08:46 +00001748static int
Steve Dowercc16be82016-09-08 10:35:16 -07001749win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001750{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001751 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001752}
1753
Martin v. Löwis14694662006-02-03 12:54:16 +00001754#endif /* MS_WINDOWS */
1755
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001756PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001757"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001758This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001759 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001760or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1761\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001762Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1763or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001764\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001766
1767static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 {"st_mode", "protection bits"},
1769 {"st_ino", "inode"},
1770 {"st_dev", "device"},
1771 {"st_nlink", "number of hard links"},
1772 {"st_uid", "user ID of owner"},
1773 {"st_gid", "group ID of owner"},
1774 {"st_size", "total size, in bytes"},
1775 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1776 {NULL, "integer time of last access"},
1777 {NULL, "integer time of last modification"},
1778 {NULL, "integer time of last change"},
1779 {"st_atime", "time of last access"},
1780 {"st_mtime", "time of last modification"},
1781 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001782 {"st_atime_ns", "time of last access in nanoseconds"},
1783 {"st_mtime_ns", "time of last modification in nanoseconds"},
1784 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001785#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001786 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001787#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001788#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001790#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001791#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001793#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001794#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001795 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001796#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001797#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001798 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001799#endif
1800#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001801 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001802#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001803#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1804 {"st_file_attributes", "Windows file attribute bits"},
1805#endif
jcea6c51d512018-01-28 14:00:08 +01001806#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1807 {"st_fstype", "Type of filesystem"},
1808#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001810};
1811
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001812#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001813#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001814#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001815#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001816#endif
1817
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001818#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001819#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1820#else
1821#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1822#endif
1823
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001824#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001825#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1826#else
1827#define ST_RDEV_IDX ST_BLOCKS_IDX
1828#endif
1829
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001830#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1831#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1832#else
1833#define ST_FLAGS_IDX ST_RDEV_IDX
1834#endif
1835
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001837#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001838#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001839#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001840#endif
1841
1842#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1843#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1844#else
1845#define ST_BIRTHTIME_IDX ST_GEN_IDX
1846#endif
1847
Zachary Ware63f277b2014-06-19 09:46:37 -05001848#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1849#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1850#else
1851#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1852#endif
1853
jcea6c51d512018-01-28 14:00:08 +01001854#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1855#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1856#else
1857#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1858#endif
1859
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001860static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 "stat_result", /* name */
1862 stat_result__doc__, /* doc */
1863 stat_result_fields,
1864 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001865};
1866
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001867PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1869This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001870 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001871or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001872\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001873See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001874
1875static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 {"f_bsize", },
1877 {"f_frsize", },
1878 {"f_blocks", },
1879 {"f_bfree", },
1880 {"f_bavail", },
1881 {"f_files", },
1882 {"f_ffree", },
1883 {"f_favail", },
1884 {"f_flag", },
1885 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001886 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001888};
1889
1890static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001891 "statvfs_result", /* name */
1892 statvfs_result__doc__, /* doc */
1893 statvfs_result_fields,
1894 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001895};
1896
Ross Lagerwall7807c352011-03-17 20:20:30 +02001897#if defined(HAVE_WAITID) && !defined(__APPLE__)
1898PyDoc_STRVAR(waitid_result__doc__,
1899"waitid_result: Result from waitid.\n\n\
1900This object may be accessed either as a tuple of\n\
1901 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1902or via the attributes si_pid, si_uid, and so on.\n\
1903\n\
1904See os.waitid for more information.");
1905
1906static PyStructSequence_Field waitid_result_fields[] = {
1907 {"si_pid", },
1908 {"si_uid", },
1909 {"si_signo", },
1910 {"si_status", },
1911 {"si_code", },
1912 {0}
1913};
1914
1915static PyStructSequence_Desc waitid_result_desc = {
1916 "waitid_result", /* name */
1917 waitid_result__doc__, /* doc */
1918 waitid_result_fields,
1919 5
1920};
1921static PyTypeObject WaitidResultType;
1922#endif
1923
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001924static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001925static PyTypeObject StatResultType;
1926static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001927#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001928static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001929#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001930static newfunc structseq_new;
1931
1932static PyObject *
1933statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1934{
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 PyStructSequence *result;
1936 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001937
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 result = (PyStructSequence*)structseq_new(type, args, kwds);
1939 if (!result)
1940 return NULL;
1941 /* If we have been initialized from a tuple,
1942 st_?time might be set to None. Initialize it
1943 from the int slots. */
1944 for (i = 7; i <= 9; i++) {
1945 if (result->ob_item[i+3] == Py_None) {
1946 Py_DECREF(Py_None);
1947 Py_INCREF(result->ob_item[i]);
1948 result->ob_item[i+3] = result->ob_item[i];
1949 }
1950 }
1951 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001952}
1953
1954
Larry Hastings6fe20b32012-04-19 15:07:49 -07001955static PyObject *billion = NULL;
1956
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001957static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001958fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001959{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001960 PyObject *s = _PyLong_FromTime_t(sec);
1961 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1962 PyObject *s_in_ns = NULL;
1963 PyObject *ns_total = NULL;
1964 PyObject *float_s = NULL;
1965
1966 if (!(s && ns_fractional))
1967 goto exit;
1968
1969 s_in_ns = PyNumber_Multiply(s, billion);
1970 if (!s_in_ns)
1971 goto exit;
1972
1973 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1974 if (!ns_total)
1975 goto exit;
1976
Victor Stinner01b5aab2017-10-24 02:02:00 -07001977 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1978 if (!float_s) {
1979 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001980 }
1981
1982 PyStructSequence_SET_ITEM(v, index, s);
1983 PyStructSequence_SET_ITEM(v, index+3, float_s);
1984 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1985 s = NULL;
1986 float_s = NULL;
1987 ns_total = NULL;
1988exit:
1989 Py_XDECREF(s);
1990 Py_XDECREF(ns_fractional);
1991 Py_XDECREF(s_in_ns);
1992 Py_XDECREF(ns_total);
1993 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001994}
1995
Tim Peters5aa91602002-01-30 05:46:57 +00001996/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001997 (used by posix_stat() and posix_fstat()) */
1998static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001999_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002000{
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 unsigned long ansec, mnsec, cnsec;
2002 PyObject *v = PyStructSequence_New(&StatResultType);
2003 if (v == NULL)
2004 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002005
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002007 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002008 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002009#ifdef MS_WINDOWS
2010 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002011#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002012 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002013#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002015#if defined(MS_WINDOWS)
2016 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2017 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2018#else
2019 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2020 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2021#endif
xdegaye50e86032017-05-22 11:15:08 +02002022 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2023 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002024
Martin v. Löwis14694662006-02-03 12:54:16 +00002025#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 ansec = st->st_atim.tv_nsec;
2027 mnsec = st->st_mtim.tv_nsec;
2028 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002029#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 ansec = st->st_atimespec.tv_nsec;
2031 mnsec = st->st_mtimespec.tv_nsec;
2032 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002033#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 ansec = st->st_atime_nsec;
2035 mnsec = st->st_mtime_nsec;
2036 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002037#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002039#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002040 fill_time(v, 7, st->st_atime, ansec);
2041 fill_time(v, 8, st->st_mtime, mnsec);
2042 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002043
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002044#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2046 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002047#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002048#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2050 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002051#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002052#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2054 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002055#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002056#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2058 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002059#endif
2060#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002061 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002062 PyObject *val;
2063 unsigned long bsec,bnsec;
2064 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002065#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002066 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002067#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002068 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002069#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002070 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002071 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2072 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002074#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002075#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2077 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002078#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002079#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2080 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2081 PyLong_FromUnsignedLong(st->st_file_attributes));
2082#endif
jcea6c51d512018-01-28 14:00:08 +01002083#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2084 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2085 PyUnicode_FromString(st->st_fstype));
2086#endif
Fred Drake699f3522000-06-29 21:12:41 +00002087
Victor Stinner8c62be82010-05-06 00:08:46 +00002088 if (PyErr_Occurred()) {
2089 Py_DECREF(v);
2090 return NULL;
2091 }
Fred Drake699f3522000-06-29 21:12:41 +00002092
Victor Stinner8c62be82010-05-06 00:08:46 +00002093 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002094}
2095
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002096/* POSIX methods */
2097
Guido van Rossum94f6f721999-01-06 18:42:14 +00002098
2099static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002100posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002101 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002102{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002103 STRUCT_STAT st;
2104 int result;
2105
2106#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2107 if (follow_symlinks_specified(function_name, follow_symlinks))
2108 return NULL;
2109#endif
2110
2111 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2112 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2113 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2114 return NULL;
2115
2116 Py_BEGIN_ALLOW_THREADS
2117 if (path->fd != -1)
2118 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002119#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002120 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002121 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002122 else
Steve Dowercc16be82016-09-08 10:35:16 -07002123 result = win32_lstat(path->wide, &st);
2124#else
2125 else
2126#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002127 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2128 result = LSTAT(path->narrow, &st);
2129 else
Steve Dowercc16be82016-09-08 10:35:16 -07002130#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002131#ifdef HAVE_FSTATAT
2132 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2133 result = fstatat(dir_fd, path->narrow, &st,
2134 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2135 else
Steve Dowercc16be82016-09-08 10:35:16 -07002136#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002137 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002138#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002139 Py_END_ALLOW_THREADS
2140
Victor Stinner292c8352012-10-30 02:17:38 +01002141 if (result != 0) {
2142 return path_error(path);
2143 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002144
2145 return _pystat_fromstructstat(&st);
2146}
2147
Larry Hastings2f936352014-08-05 14:04:04 +10002148/*[python input]
2149
2150for s in """
2151
2152FACCESSAT
2153FCHMODAT
2154FCHOWNAT
2155FSTATAT
2156LINKAT
2157MKDIRAT
2158MKFIFOAT
2159MKNODAT
2160OPENAT
2161READLINKAT
2162SYMLINKAT
2163UNLINKAT
2164
2165""".strip().split():
2166 s = s.strip()
2167 print("""
2168#ifdef HAVE_{s}
2169 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002170#else
Larry Hastings2f936352014-08-05 14:04:04 +10002171 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002172#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002173""".rstrip().format(s=s))
2174
2175for s in """
2176
2177FCHDIR
2178FCHMOD
2179FCHOWN
2180FDOPENDIR
2181FEXECVE
2182FPATHCONF
2183FSTATVFS
2184FTRUNCATE
2185
2186""".strip().split():
2187 s = s.strip()
2188 print("""
2189#ifdef HAVE_{s}
2190 #define PATH_HAVE_{s} 1
2191#else
2192 #define PATH_HAVE_{s} 0
2193#endif
2194
2195""".rstrip().format(s=s))
2196[python start generated code]*/
2197
2198#ifdef HAVE_FACCESSAT
2199 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2200#else
2201 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2202#endif
2203
2204#ifdef HAVE_FCHMODAT
2205 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2206#else
2207 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2208#endif
2209
2210#ifdef HAVE_FCHOWNAT
2211 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2212#else
2213 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2214#endif
2215
2216#ifdef HAVE_FSTATAT
2217 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2218#else
2219 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2220#endif
2221
2222#ifdef HAVE_LINKAT
2223 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2224#else
2225 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2226#endif
2227
2228#ifdef HAVE_MKDIRAT
2229 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2230#else
2231 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2232#endif
2233
2234#ifdef HAVE_MKFIFOAT
2235 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2236#else
2237 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2238#endif
2239
2240#ifdef HAVE_MKNODAT
2241 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2242#else
2243 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2244#endif
2245
2246#ifdef HAVE_OPENAT
2247 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2248#else
2249 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2250#endif
2251
2252#ifdef HAVE_READLINKAT
2253 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2254#else
2255 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2256#endif
2257
2258#ifdef HAVE_SYMLINKAT
2259 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2260#else
2261 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2262#endif
2263
2264#ifdef HAVE_UNLINKAT
2265 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2266#else
2267 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2268#endif
2269
2270#ifdef HAVE_FCHDIR
2271 #define PATH_HAVE_FCHDIR 1
2272#else
2273 #define PATH_HAVE_FCHDIR 0
2274#endif
2275
2276#ifdef HAVE_FCHMOD
2277 #define PATH_HAVE_FCHMOD 1
2278#else
2279 #define PATH_HAVE_FCHMOD 0
2280#endif
2281
2282#ifdef HAVE_FCHOWN
2283 #define PATH_HAVE_FCHOWN 1
2284#else
2285 #define PATH_HAVE_FCHOWN 0
2286#endif
2287
2288#ifdef HAVE_FDOPENDIR
2289 #define PATH_HAVE_FDOPENDIR 1
2290#else
2291 #define PATH_HAVE_FDOPENDIR 0
2292#endif
2293
2294#ifdef HAVE_FEXECVE
2295 #define PATH_HAVE_FEXECVE 1
2296#else
2297 #define PATH_HAVE_FEXECVE 0
2298#endif
2299
2300#ifdef HAVE_FPATHCONF
2301 #define PATH_HAVE_FPATHCONF 1
2302#else
2303 #define PATH_HAVE_FPATHCONF 0
2304#endif
2305
2306#ifdef HAVE_FSTATVFS
2307 #define PATH_HAVE_FSTATVFS 1
2308#else
2309 #define PATH_HAVE_FSTATVFS 0
2310#endif
2311
2312#ifdef HAVE_FTRUNCATE
2313 #define PATH_HAVE_FTRUNCATE 1
2314#else
2315 #define PATH_HAVE_FTRUNCATE 0
2316#endif
2317/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002318
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002319#ifdef MS_WINDOWS
2320 #undef PATH_HAVE_FTRUNCATE
2321 #define PATH_HAVE_FTRUNCATE 1
2322#endif
Larry Hastings31826802013-10-19 00:09:25 -07002323
Larry Hastings61272b72014-01-07 12:41:53 -08002324/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002325
2326class path_t_converter(CConverter):
2327
2328 type = "path_t"
2329 impl_by_reference = True
2330 parse_by_reference = True
2331
2332 converter = 'path_converter'
2333
2334 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002335 # right now path_t doesn't support default values.
2336 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002337 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002338 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002339
Larry Hastings2f936352014-08-05 14:04:04 +10002340 if self.c_default not in (None, 'Py_None'):
2341 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002342
2343 self.nullable = nullable
2344 self.allow_fd = allow_fd
2345
Larry Hastings7726ac92014-01-31 22:03:12 -08002346 def pre_render(self):
2347 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002348 if isinstance(value, str):
2349 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002350 return str(int(bool(value)))
2351
2352 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002353 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002354 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002355 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002356 strify(self.nullable),
2357 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002358 )
2359
2360 def cleanup(self):
2361 return "path_cleanup(&" + self.name + ");\n"
2362
2363
2364class dir_fd_converter(CConverter):
2365 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002366
Larry Hastings2f936352014-08-05 14:04:04 +10002367 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002368 if self.default in (unspecified, None):
2369 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002370 if isinstance(requires, str):
2371 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2372 else:
2373 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002374
Larry Hastings2f936352014-08-05 14:04:04 +10002375class fildes_converter(CConverter):
2376 type = 'int'
2377 converter = 'fildes_converter'
2378
2379class uid_t_converter(CConverter):
2380 type = "uid_t"
2381 converter = '_Py_Uid_Converter'
2382
2383class gid_t_converter(CConverter):
2384 type = "gid_t"
2385 converter = '_Py_Gid_Converter'
2386
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002387class dev_t_converter(CConverter):
2388 type = 'dev_t'
2389 converter = '_Py_Dev_Converter'
2390
2391class dev_t_return_converter(unsigned_long_return_converter):
2392 type = 'dev_t'
2393 conversion_fn = '_PyLong_FromDev'
2394 unsigned_cast = '(dev_t)'
2395
Larry Hastings2f936352014-08-05 14:04:04 +10002396class FSConverter_converter(CConverter):
2397 type = 'PyObject *'
2398 converter = 'PyUnicode_FSConverter'
2399 def converter_init(self):
2400 if self.default is not unspecified:
2401 fail("FSConverter_converter does not support default values")
2402 self.c_default = 'NULL'
2403
2404 def cleanup(self):
2405 return "Py_XDECREF(" + self.name + ");\n"
2406
2407class pid_t_converter(CConverter):
2408 type = 'pid_t'
2409 format_unit = '" _Py_PARSE_PID "'
2410
2411class idtype_t_converter(int_converter):
2412 type = 'idtype_t'
2413
2414class id_t_converter(CConverter):
2415 type = 'id_t'
2416 format_unit = '" _Py_PARSE_PID "'
2417
Benjamin Petersonca470632016-09-06 13:47:26 -07002418class intptr_t_converter(CConverter):
2419 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002420 format_unit = '" _Py_PARSE_INTPTR "'
2421
2422class Py_off_t_converter(CConverter):
2423 type = 'Py_off_t'
2424 converter = 'Py_off_t_converter'
2425
2426class Py_off_t_return_converter(long_return_converter):
2427 type = 'Py_off_t'
2428 conversion_fn = 'PyLong_FromPy_off_t'
2429
2430class path_confname_converter(CConverter):
2431 type="int"
2432 converter="conv_path_confname"
2433
2434class confstr_confname_converter(path_confname_converter):
2435 converter='conv_confstr_confname'
2436
2437class sysconf_confname_converter(path_confname_converter):
2438 converter="conv_sysconf_confname"
2439
2440class sched_param_converter(CConverter):
2441 type = 'struct sched_param'
2442 converter = 'convert_sched_param'
2443 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002444
Larry Hastings61272b72014-01-07 12:41:53 -08002445[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002446/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002447
Larry Hastings61272b72014-01-07 12:41:53 -08002448/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002449
Larry Hastings2a727912014-01-16 11:32:01 -08002450os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002451
2452 path : path_t(allow_fd=True)
BNMetrics08026b12018-11-02 17:56:25 +00002453 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002454 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002455
2456 *
2457
Larry Hastings2f936352014-08-05 14:04:04 +10002458 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002459 If not None, it should be a file descriptor open to a directory,
2460 and path should be a relative string; path will then be relative to
2461 that directory.
2462
2463 follow_symlinks: bool = True
2464 If False, and the last element of the path is a symbolic link,
2465 stat will examine the symbolic link itself instead of the file
2466 the link points to.
2467
2468Perform a stat system call on the given path.
2469
2470dir_fd and follow_symlinks may not be implemented
2471 on your platform. If they are unavailable, using them will raise a
2472 NotImplementedError.
2473
2474It's an error to use dir_fd or follow_symlinks when specifying path as
2475 an open file descriptor.
2476
Larry Hastings61272b72014-01-07 12:41:53 -08002477[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002478
Larry Hastings31826802013-10-19 00:09:25 -07002479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002480os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002481/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002482{
2483 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2484}
2485
Larry Hastings2f936352014-08-05 14:04:04 +10002486
2487/*[clinic input]
2488os.lstat
2489
2490 path : path_t
2491
2492 *
2493
2494 dir_fd : dir_fd(requires='fstatat') = None
2495
2496Perform a stat system call on the given path, without following symbolic links.
2497
2498Like stat(), but do not follow symbolic links.
2499Equivalent to stat(path, follow_symlinks=False).
2500[clinic start generated code]*/
2501
Larry Hastings2f936352014-08-05 14:04:04 +10002502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002503os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2504/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002505{
2506 int follow_symlinks = 0;
2507 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2508}
Larry Hastings31826802013-10-19 00:09:25 -07002509
Larry Hastings2f936352014-08-05 14:04:04 +10002510
Larry Hastings61272b72014-01-07 12:41:53 -08002511/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002512os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002513
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002514 path: path_t
BNMetrics08026b12018-11-02 17:56:25 +00002515 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002516
2517 mode: int
2518 Operating-system mode bitfield. Can be F_OK to test existence,
2519 or the inclusive-OR of R_OK, W_OK, and X_OK.
2520
2521 *
2522
Larry Hastings2f936352014-08-05 14:04:04 +10002523 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002524 If not None, it should be a file descriptor open to a directory,
2525 and path should be relative; path will then be relative to that
2526 directory.
2527
2528 effective_ids: bool = False
2529 If True, access will use the effective uid/gid instead of
2530 the real uid/gid.
2531
2532 follow_symlinks: bool = True
2533 If False, and the last element of the path is a symbolic link,
2534 access will examine the symbolic link itself instead of the file
2535 the link points to.
2536
2537Use the real uid/gid to test for access to a path.
2538
2539{parameters}
2540dir_fd, effective_ids, and follow_symlinks may not be implemented
2541 on your platform. If they are unavailable, using them will raise a
2542 NotImplementedError.
2543
2544Note that most operations will use the effective uid/gid, therefore this
2545 routine can be used in a suid/sgid environment to test if the invoking user
2546 has the specified access to the path.
2547
Larry Hastings61272b72014-01-07 12:41:53 -08002548[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002549
Larry Hastings2f936352014-08-05 14:04:04 +10002550static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002551os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002552 int effective_ids, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002553/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002554{
Larry Hastings2f936352014-08-05 14:04:04 +10002555 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002556
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002557#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002558 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002559#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002561#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562
Larry Hastings9cf065c2012-06-22 16:30:09 -07002563#ifndef HAVE_FACCESSAT
2564 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002565 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002566
2567 if (effective_ids) {
2568 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002569 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002570 }
2571#endif
2572
2573#ifdef MS_WINDOWS
2574 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002575 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576 Py_END_ALLOW_THREADS
2577
2578 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002579 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002580 * * we didn't get a -1, and
2581 * * write access wasn't requested,
2582 * * or the file isn't read-only,
2583 * * or it's a directory.
2584 * (Directories cannot be read-only on Windows.)
2585 */
Larry Hastings2f936352014-08-05 14:04:04 +10002586 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002587 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002588 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002589 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002590#else
2591
2592 Py_BEGIN_ALLOW_THREADS
2593#ifdef HAVE_FACCESSAT
2594 if ((dir_fd != DEFAULT_DIR_FD) ||
2595 effective_ids ||
2596 !follow_symlinks) {
2597 int flags = 0;
2598 if (!follow_symlinks)
2599 flags |= AT_SYMLINK_NOFOLLOW;
2600 if (effective_ids)
2601 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002602 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 }
2604 else
2605#endif
Larry Hastings31826802013-10-19 00:09:25 -07002606 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002608 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002609#endif
2610
Larry Hastings9cf065c2012-06-22 16:30:09 -07002611 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002612}
2613
Guido van Rossumd371ff11999-01-25 16:12:23 +00002614#ifndef F_OK
2615#define F_OK 0
2616#endif
2617#ifndef R_OK
2618#define R_OK 4
2619#endif
2620#ifndef W_OK
2621#define W_OK 2
2622#endif
2623#ifndef X_OK
2624#define X_OK 1
2625#endif
2626
Larry Hastings31826802013-10-19 00:09:25 -07002627
Guido van Rossumd371ff11999-01-25 16:12:23 +00002628#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002629/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002630os.ttyname -> DecodeFSDefault
2631
2632 fd: int
2633 Integer file descriptor handle.
2634
2635 /
2636
2637Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002638[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002639
Larry Hastings31826802013-10-19 00:09:25 -07002640static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002641os_ttyname_impl(PyObject *module, int fd)
2642/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002643{
2644 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002645
Larry Hastings31826802013-10-19 00:09:25 -07002646 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002647 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002648 posix_error();
2649 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002650}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002651#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002652
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002653#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002654/*[clinic input]
2655os.ctermid
2656
2657Return the name of the controlling terminal for this process.
2658[clinic start generated code]*/
2659
Larry Hastings2f936352014-08-05 14:04:04 +10002660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002661os_ctermid_impl(PyObject *module)
2662/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002663{
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 char *ret;
2665 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002666
Greg Wardb48bc172000-03-01 21:51:56 +00002667#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002669#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002670 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 if (ret == NULL)
2673 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002674 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002675}
Larry Hastings2f936352014-08-05 14:04:04 +10002676#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002677
Larry Hastings2f936352014-08-05 14:04:04 +10002678
2679/*[clinic input]
2680os.chdir
2681
2682 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2683
2684Change the current working directory to the specified path.
2685
2686path may always be specified as a string.
2687On some platforms, path may also be specified as an open file descriptor.
2688 If this functionality is unavailable, using it raises an exception.
2689[clinic start generated code]*/
2690
Larry Hastings2f936352014-08-05 14:04:04 +10002691static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002692os_chdir_impl(PyObject *module, path_t *path)
2693/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002694{
2695 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002696
2697 Py_BEGIN_ALLOW_THREADS
2698#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002699 /* on unix, success = 0, on windows, success = !0 */
2700 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701#else
2702#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002703 if (path->fd != -1)
2704 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002705 else
2706#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002707 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002708#endif
2709 Py_END_ALLOW_THREADS
2710
2711 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002712 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002713 }
2714
Larry Hastings2f936352014-08-05 14:04:04 +10002715 Py_RETURN_NONE;
2716}
2717
2718
2719#ifdef HAVE_FCHDIR
2720/*[clinic input]
2721os.fchdir
2722
2723 fd: fildes
2724
2725Change to the directory of the given file descriptor.
2726
2727fd must be opened on a directory, not a file.
2728Equivalent to os.chdir(fd).
2729
2730[clinic start generated code]*/
2731
Fred Drake4d1e64b2002-04-15 19:40:07 +00002732static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002733os_fchdir_impl(PyObject *module, int fd)
2734/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002735{
Larry Hastings2f936352014-08-05 14:04:04 +10002736 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002737}
2738#endif /* HAVE_FCHDIR */
2739
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002740
Larry Hastings2f936352014-08-05 14:04:04 +10002741/*[clinic input]
2742os.chmod
2743
2744 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetrics08026b12018-11-02 17:56:25 +00002745 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002746 On some platforms, path may also be specified as an open file descriptor.
2747 If this functionality is unavailable, using it raises an exception.
2748
2749 mode: int
2750 Operating-system mode bitfield.
2751
2752 *
2753
2754 dir_fd : dir_fd(requires='fchmodat') = None
2755 If not None, it should be a file descriptor open to a directory,
2756 and path should be relative; path will then be relative to that
2757 directory.
2758
2759 follow_symlinks: bool = True
2760 If False, and the last element of the path is a symbolic link,
2761 chmod will modify the symbolic link itself instead of the file
2762 the link points to.
2763
2764Change the access permissions of a file.
2765
2766It is an error to use dir_fd or follow_symlinks when specifying path as
2767 an open file descriptor.
2768dir_fd and follow_symlinks may not be implemented on your platform.
2769 If they are unavailable, using them will raise a NotImplementedError.
2770
2771[clinic start generated code]*/
2772
Larry Hastings2f936352014-08-05 14:04:04 +10002773static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002774os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002775 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002776/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002777{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002779
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002780#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002781 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002783
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#ifdef HAVE_FCHMODAT
2785 int fchmodat_nofollow_unsupported = 0;
2786#endif
2787
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2789 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002790 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002791#endif
2792
2793#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002794 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002795 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002796 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797 result = 0;
2798 else {
2799 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002800 attr &= ~FILE_ATTRIBUTE_READONLY;
2801 else
2802 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002803 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804 }
2805 Py_END_ALLOW_THREADS
2806
2807 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002808 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809 }
2810#else /* MS_WINDOWS */
2811 Py_BEGIN_ALLOW_THREADS
2812#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002813 if (path->fd != -1)
2814 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002815 else
2816#endif
2817#ifdef HAVE_LCHMOD
2818 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002819 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820 else
2821#endif
2822#ifdef HAVE_FCHMODAT
2823 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2824 /*
2825 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2826 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002827 * and then says it isn't implemented yet.
2828 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 *
2830 * Once it is supported, os.chmod will automatically
2831 * support dir_fd and follow_symlinks=False. (Hopefully.)
2832 * Until then, we need to be careful what exception we raise.
2833 */
Larry Hastings2f936352014-08-05 14:04:04 +10002834 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2836 /*
2837 * But wait! We can't throw the exception without allowing threads,
2838 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2839 */
2840 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002841 result &&
2842 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2843 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002844 }
2845 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002846#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002847 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002848 Py_END_ALLOW_THREADS
2849
2850 if (result) {
2851#ifdef HAVE_FCHMODAT
2852 if (fchmodat_nofollow_unsupported) {
2853 if (dir_fd != DEFAULT_DIR_FD)
2854 dir_fd_and_follow_symlinks_invalid("chmod",
2855 dir_fd, follow_symlinks);
2856 else
2857 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002858 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 }
2860 else
2861#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002862 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002863 }
2864#endif
2865
Larry Hastings2f936352014-08-05 14:04:04 +10002866 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002867}
2868
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869
Christian Heimes4e30a842007-11-30 22:12:06 +00002870#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002871/*[clinic input]
2872os.fchmod
2873
2874 fd: int
2875 mode: int
2876
2877Change the access permissions of the file given by file descriptor fd.
2878
2879Equivalent to os.chmod(fd, mode).
2880[clinic start generated code]*/
2881
Larry Hastings2f936352014-08-05 14:04:04 +10002882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002883os_fchmod_impl(PyObject *module, int fd, int mode)
2884/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002885{
2886 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002887 int async_err = 0;
2888
2889 do {
2890 Py_BEGIN_ALLOW_THREADS
2891 res = fchmod(fd, mode);
2892 Py_END_ALLOW_THREADS
2893 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2894 if (res != 0)
2895 return (!async_err) ? posix_error() : NULL;
2896
Victor Stinner8c62be82010-05-06 00:08:46 +00002897 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002898}
2899#endif /* HAVE_FCHMOD */
2900
Larry Hastings2f936352014-08-05 14:04:04 +10002901
Christian Heimes4e30a842007-11-30 22:12:06 +00002902#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002903/*[clinic input]
2904os.lchmod
2905
2906 path: path_t
2907 mode: int
2908
2909Change the access permissions of a file, without following symbolic links.
2910
2911If path is a symlink, this affects the link itself rather than the target.
2912Equivalent to chmod(path, mode, follow_symlinks=False)."
2913[clinic start generated code]*/
2914
Larry Hastings2f936352014-08-05 14:04:04 +10002915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002916os_lchmod_impl(PyObject *module, path_t *path, int mode)
2917/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002918{
Victor Stinner8c62be82010-05-06 00:08:46 +00002919 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002920 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002921 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002923 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002924 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002925 return NULL;
2926 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002928}
2929#endif /* HAVE_LCHMOD */
2930
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002931
Thomas Wouterscf297e42007-02-23 15:07:44 +00002932#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002933/*[clinic input]
2934os.chflags
2935
2936 path: path_t
2937 flags: unsigned_long(bitwise=True)
2938 follow_symlinks: bool=True
2939
2940Set file flags.
2941
2942If follow_symlinks is False, and the last element of the path is a symbolic
2943 link, chflags will change flags on the symbolic link itself instead of the
2944 file the link points to.
2945follow_symlinks may not be implemented on your platform. If it is
2946unavailable, using it will raise a NotImplementedError.
2947
2948[clinic start generated code]*/
2949
Larry Hastings2f936352014-08-05 14:04:04 +10002950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002951os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002952 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002953/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002954{
2955 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956
2957#ifndef HAVE_LCHFLAGS
2958 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002959 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002960#endif
2961
Victor Stinner8c62be82010-05-06 00:08:46 +00002962 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002963#ifdef HAVE_LCHFLAGS
2964 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002965 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966 else
2967#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002968 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002970
Larry Hastings2f936352014-08-05 14:04:04 +10002971 if (result)
2972 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002973
Larry Hastings2f936352014-08-05 14:04:04 +10002974 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002975}
2976#endif /* HAVE_CHFLAGS */
2977
Larry Hastings2f936352014-08-05 14:04:04 +10002978
Thomas Wouterscf297e42007-02-23 15:07:44 +00002979#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002980/*[clinic input]
2981os.lchflags
2982
2983 path: path_t
2984 flags: unsigned_long(bitwise=True)
2985
2986Set file flags.
2987
2988This function will not follow symbolic links.
2989Equivalent to chflags(path, flags, follow_symlinks=False).
2990[clinic start generated code]*/
2991
Larry Hastings2f936352014-08-05 14:04:04 +10002992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002993os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2994/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002995{
Victor Stinner8c62be82010-05-06 00:08:46 +00002996 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002997 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002998 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002999 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003000 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003001 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003002 }
Victor Stinner292c8352012-10-30 02:17:38 +01003003 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003004}
3005#endif /* HAVE_LCHFLAGS */
3006
Larry Hastings2f936352014-08-05 14:04:04 +10003007
Martin v. Löwis244edc82001-10-04 22:44:26 +00003008#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003009/*[clinic input]
3010os.chroot
3011 path: path_t
3012
3013Change root directory to path.
3014
3015[clinic start generated code]*/
3016
Larry Hastings2f936352014-08-05 14:04:04 +10003017static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003018os_chroot_impl(PyObject *module, path_t *path)
3019/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003020{
3021 int res;
3022 Py_BEGIN_ALLOW_THREADS
3023 res = chroot(path->narrow);
3024 Py_END_ALLOW_THREADS
3025 if (res < 0)
3026 return path_error(path);
3027 Py_RETURN_NONE;
3028}
3029#endif /* HAVE_CHROOT */
3030
Martin v. Löwis244edc82001-10-04 22:44:26 +00003031
Guido van Rossum21142a01999-01-08 21:05:37 +00003032#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003033/*[clinic input]
3034os.fsync
3035
3036 fd: fildes
3037
3038Force write of fd to disk.
3039[clinic start generated code]*/
3040
Larry Hastings2f936352014-08-05 14:04:04 +10003041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003042os_fsync_impl(PyObject *module, int fd)
3043/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003044{
3045 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003046}
3047#endif /* HAVE_FSYNC */
3048
Larry Hastings2f936352014-08-05 14:04:04 +10003049
Ross Lagerwall7807c352011-03-17 20:20:30 +02003050#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003051/*[clinic input]
3052os.sync
3053
3054Force write of everything to disk.
3055[clinic start generated code]*/
3056
Larry Hastings2f936352014-08-05 14:04:04 +10003057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003058os_sync_impl(PyObject *module)
3059/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003060{
3061 Py_BEGIN_ALLOW_THREADS
3062 sync();
3063 Py_END_ALLOW_THREADS
3064 Py_RETURN_NONE;
3065}
Larry Hastings2f936352014-08-05 14:04:04 +10003066#endif /* HAVE_SYNC */
3067
Ross Lagerwall7807c352011-03-17 20:20:30 +02003068
Guido van Rossum21142a01999-01-08 21:05:37 +00003069#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003070#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003071extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3072#endif
3073
Larry Hastings2f936352014-08-05 14:04:04 +10003074/*[clinic input]
3075os.fdatasync
3076
3077 fd: fildes
3078
3079Force write of fd to disk without forcing update of metadata.
3080[clinic start generated code]*/
3081
Larry Hastings2f936352014-08-05 14:04:04 +10003082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003083os_fdatasync_impl(PyObject *module, int fd)
3084/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003085{
3086 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003087}
3088#endif /* HAVE_FDATASYNC */
3089
3090
Fredrik Lundh10723342000-07-10 16:38:09 +00003091#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003092/*[clinic input]
3093os.chown
3094
3095 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetrics08026b12018-11-02 17:56:25 +00003096 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003097
3098 uid: uid_t
3099
3100 gid: gid_t
3101
3102 *
3103
3104 dir_fd : dir_fd(requires='fchownat') = None
3105 If not None, it should be a file descriptor open to a directory,
3106 and path should be relative; path will then be relative to that
3107 directory.
3108
3109 follow_symlinks: bool = True
3110 If False, and the last element of the path is a symbolic link,
3111 stat will examine the symbolic link itself instead of the file
3112 the link points to.
3113
3114Change the owner and group id of path to the numeric uid and gid.\
3115
3116path may always be specified as a string.
3117On some platforms, path may also be specified as an open file descriptor.
3118 If this functionality is unavailable, using it raises an exception.
3119If dir_fd is not None, it should be a file descriptor open to a directory,
3120 and path should be relative; path will then be relative to that directory.
3121If follow_symlinks is False, and the last element of the path is a symbolic
3122 link, chown will modify the symbolic link itself instead of the file the
3123 link points to.
3124It is an error to use dir_fd or follow_symlinks when specifying path as
3125 an open file descriptor.
3126dir_fd and follow_symlinks may not be implemented on your platform.
3127 If they are unavailable, using them will raise a NotImplementedError.
3128
3129[clinic start generated code]*/
3130
Larry Hastings2f936352014-08-05 14:04:04 +10003131static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003132os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003133 int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00003134/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003135{
3136 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137
3138#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3139 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003142 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3143 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3144 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003145
3146#ifdef __APPLE__
3147 /*
3148 * This is for Mac OS X 10.3, which doesn't have lchown.
3149 * (But we still have an lchown symbol because of weak-linking.)
3150 * It doesn't have fchownat either. So there's no possibility
3151 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003152 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153 if ((!follow_symlinks) && (lchown == NULL)) {
3154 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003155 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156 }
3157#endif
3158
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003160#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003161 if (path->fd != -1)
3162 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163 else
3164#endif
3165#ifdef HAVE_LCHOWN
3166 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003167 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003168 else
3169#endif
3170#ifdef HAVE_FCHOWNAT
3171 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003172 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003173 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3174 else
3175#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003176 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003178
Larry Hastings2f936352014-08-05 14:04:04 +10003179 if (result)
3180 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181
Larry Hastings2f936352014-08-05 14:04:04 +10003182 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003183}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003184#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003185
Larry Hastings2f936352014-08-05 14:04:04 +10003186
Christian Heimes4e30a842007-11-30 22:12:06 +00003187#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003188/*[clinic input]
3189os.fchown
3190
3191 fd: int
3192 uid: uid_t
3193 gid: gid_t
3194
3195Change the owner and group id of the file specified by file descriptor.
3196
3197Equivalent to os.chown(fd, uid, gid).
3198
3199[clinic start generated code]*/
3200
Larry Hastings2f936352014-08-05 14:04:04 +10003201static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003202os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3203/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003204{
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003206 int async_err = 0;
3207
3208 do {
3209 Py_BEGIN_ALLOW_THREADS
3210 res = fchown(fd, uid, gid);
3211 Py_END_ALLOW_THREADS
3212 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3213 if (res != 0)
3214 return (!async_err) ? posix_error() : NULL;
3215
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003217}
3218#endif /* HAVE_FCHOWN */
3219
Larry Hastings2f936352014-08-05 14:04:04 +10003220
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003221#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003222/*[clinic input]
3223os.lchown
3224
3225 path : path_t
3226 uid: uid_t
3227 gid: gid_t
3228
3229Change the owner and group id of path to the numeric uid and gid.
3230
3231This function will not follow symbolic links.
3232Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3233[clinic start generated code]*/
3234
Larry Hastings2f936352014-08-05 14:04:04 +10003235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003236os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3237/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003238{
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003241 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003243 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003244 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003245 }
Larry Hastings2f936352014-08-05 14:04:04 +10003246 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003247}
3248#endif /* HAVE_LCHOWN */
3249
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003250
Barry Warsaw53699e91996-12-10 23:23:01 +00003251static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003252posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003253{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003254 char *buf, *tmpbuf;
3255 char *cwd;
3256 const size_t chunk = 1024;
3257 size_t buflen = 0;
3258 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003259
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003260#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003262 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 wchar_t *wbuf2 = wbuf;
3264 PyObject *resobj;
3265 DWORD len;
3266 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003267 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003268 /* If the buffer is large enough, len does not include the
3269 terminating \0. If the buffer is too small, len includes
3270 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003271 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003272 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003273 if (wbuf2)
3274 len = GetCurrentDirectoryW(len, wbuf2);
3275 }
3276 Py_END_ALLOW_THREADS
3277 if (!wbuf2) {
3278 PyErr_NoMemory();
3279 return NULL;
3280 }
3281 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003282 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003283 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003284 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 }
3286 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003287 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003288 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 return resobj;
3290 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003291
3292 if (win32_warn_bytes_api())
3293 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003294#endif
3295
Victor Stinner4403d7d2015-04-25 00:16:10 +02003296 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003297 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003298 do {
3299 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003300#ifdef MS_WINDOWS
3301 if (buflen > INT_MAX) {
3302 PyErr_NoMemory();
3303 break;
3304 }
3305#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003306 tmpbuf = PyMem_RawRealloc(buf, buflen);
3307 if (tmpbuf == NULL)
3308 break;
3309
3310 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003311#ifdef MS_WINDOWS
3312 cwd = getcwd(buf, (int)buflen);
3313#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003314 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003315#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003316 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003317 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003318
3319 if (cwd == NULL) {
3320 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003321 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003322 }
3323
Victor Stinner8c62be82010-05-06 00:08:46 +00003324 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003325 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3326 else
3327 obj = PyUnicode_DecodeFSDefault(buf);
3328 PyMem_RawFree(buf);
3329
3330 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003331}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003332
Larry Hastings2f936352014-08-05 14:04:04 +10003333
3334/*[clinic input]
3335os.getcwd
3336
3337Return a unicode string representing the current working directory.
3338[clinic start generated code]*/
3339
Larry Hastings2f936352014-08-05 14:04:04 +10003340static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003341os_getcwd_impl(PyObject *module)
3342/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003343{
3344 return posix_getcwd(0);
3345}
3346
Larry Hastings2f936352014-08-05 14:04:04 +10003347
3348/*[clinic input]
3349os.getcwdb
3350
3351Return a bytes string representing the current working directory.
3352[clinic start generated code]*/
3353
Larry Hastings2f936352014-08-05 14:04:04 +10003354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003355os_getcwdb_impl(PyObject *module)
3356/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003357{
3358 return posix_getcwd(1);
3359}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003360
Larry Hastings2f936352014-08-05 14:04:04 +10003361
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3363#define HAVE_LINK 1
3364#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003365
Guido van Rossumb6775db1994-08-01 11:34:53 +00003366#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003367/*[clinic input]
3368
3369os.link
3370
3371 src : path_t
3372 dst : path_t
3373 *
3374 src_dir_fd : dir_fd = None
3375 dst_dir_fd : dir_fd = None
3376 follow_symlinks: bool = True
3377
3378Create a hard link to a file.
3379
3380If either src_dir_fd or dst_dir_fd is not None, it should be a file
3381 descriptor open to a directory, and the respective path string (src or dst)
3382 should be relative; the path will then be relative to that directory.
3383If follow_symlinks is False, and the last element of src is a symbolic
3384 link, link will create a link to the symbolic link itself instead of the
3385 file the link points to.
3386src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3387 platform. If they are unavailable, using them will raise a
3388 NotImplementedError.
3389[clinic start generated code]*/
3390
Larry Hastings2f936352014-08-05 14:04:04 +10003391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003392os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003393 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003394/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003395{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003397 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398#else
3399 int result;
3400#endif
3401
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402#ifndef HAVE_LINKAT
3403 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3404 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003405 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 }
3407#endif
3408
Steve Dowercc16be82016-09-08 10:35:16 -07003409#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003410 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 PyErr_SetString(PyExc_NotImplementedError,
3412 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003413 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 }
Steve Dowercc16be82016-09-08 10:35:16 -07003415#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003416
Brian Curtin1b9df392010-11-24 20:24:31 +00003417#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003418 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003419 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003421
Larry Hastings2f936352014-08-05 14:04:04 +10003422 if (!result)
3423 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424#else
3425 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003426#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3428 (dst_dir_fd != DEFAULT_DIR_FD) ||
3429 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003430 result = linkat(src_dir_fd, src->narrow,
3431 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3433 else
Steve Dowercc16be82016-09-08 10:35:16 -07003434#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003435 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003437
Larry Hastings2f936352014-08-05 14:04:04 +10003438 if (result)
3439 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003440#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441
Larry Hastings2f936352014-08-05 14:04:04 +10003442 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003443}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444#endif
3445
Brian Curtin1b9df392010-11-24 20:24:31 +00003446
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003447#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003448static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003449_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003450{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451 PyObject *v;
3452 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3453 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003454 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003456 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458
Steve Dowercc16be82016-09-08 10:35:16 -07003459 WIN32_FIND_DATAW wFileData;
3460 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003461
Steve Dowercc16be82016-09-08 10:35:16 -07003462 if (!path->wide) { /* Default arg: "." */
3463 po_wchars = L".";
3464 len = 1;
3465 } else {
3466 po_wchars = path->wide;
3467 len = wcslen(path->wide);
3468 }
3469 /* The +5 is so we can append "\\*.*\0" */
3470 wnamebuf = PyMem_New(wchar_t, len + 5);
3471 if (!wnamebuf) {
3472 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003474 }
Steve Dowercc16be82016-09-08 10:35:16 -07003475 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003477 wchar_t wch = wnamebuf[len-1];
3478 if (wch != SEP && wch != ALTSEP && wch != L':')
3479 wnamebuf[len++] = SEP;
3480 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003481 }
Steve Dowercc16be82016-09-08 10:35:16 -07003482 if ((list = PyList_New(0)) == NULL) {
3483 goto exit;
3484 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003485 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003486 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003487 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 if (hFindFile == INVALID_HANDLE_VALUE) {
3489 int error = GetLastError();
3490 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 goto exit;
3492 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003493 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 }
3496 do {
3497 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003498 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3499 wcscmp(wFileData.cFileName, L"..") != 0) {
3500 v = PyUnicode_FromWideChar(wFileData.cFileName,
3501 wcslen(wFileData.cFileName));
3502 if (path->narrow && v) {
3503 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3504 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003505 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 Py_DECREF(list);
3507 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 break;
3509 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 Py_DECREF(list);
3513 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 break;
3515 }
3516 Py_DECREF(v);
3517 }
3518 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003519 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 Py_END_ALLOW_THREADS
3521 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3522 it got to the end of the directory. */
3523 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003525 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 }
3528 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003529
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530exit:
3531 if (hFindFile != INVALID_HANDLE_VALUE) {
3532 if (FindClose(hFindFile) == FALSE) {
3533 if (list != NULL) {
3534 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003535 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 }
3537 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003539 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003540
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003542} /* end of _listdir_windows_no_opendir */
3543
3544#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3545
3546static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003547_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003548{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003549 PyObject *v;
3550 DIR *dirp = NULL;
3551 struct dirent *ep;
3552 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003553#ifdef HAVE_FDOPENDIR
3554 int fd = -1;
3555#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003556
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003559 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003561 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003562 if (fd == -1)
3563 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564
Larry Hastingsfdaea062012-06-25 04:42:23 -07003565 return_str = 1;
3566
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567 Py_BEGIN_ALLOW_THREADS
3568 dirp = fdopendir(fd);
3569 Py_END_ALLOW_THREADS
3570 }
3571 else
3572#endif
3573 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003574 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003575 if (path->narrow) {
3576 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003577 /* only return bytes if they specified a bytes-like object */
3578 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003579 }
3580 else {
3581 name = ".";
3582 return_str = 1;
3583 }
3584
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 Py_BEGIN_ALLOW_THREADS
3586 dirp = opendir(name);
3587 Py_END_ALLOW_THREADS
3588 }
3589
3590 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003591 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003592#ifdef HAVE_FDOPENDIR
3593 if (fd != -1) {
3594 Py_BEGIN_ALLOW_THREADS
3595 close(fd);
3596 Py_END_ALLOW_THREADS
3597 }
3598#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 goto exit;
3600 }
3601 if ((list = PyList_New(0)) == NULL) {
3602 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 }
3604 for (;;) {
3605 errno = 0;
3606 Py_BEGIN_ALLOW_THREADS
3607 ep = readdir(dirp);
3608 Py_END_ALLOW_THREADS
3609 if (ep == NULL) {
3610 if (errno == 0) {
3611 break;
3612 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003614 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 }
3617 }
3618 if (ep->d_name[0] == '.' &&
3619 (NAMLEN(ep) == 1 ||
3620 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3621 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003622 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003623 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3624 else
3625 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003626 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 break;
3629 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 break;
3634 }
3635 Py_DECREF(v);
3636 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003637
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638exit:
3639 if (dirp != NULL) {
3640 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003641#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 if (fd > -1)
3643 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003644#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 closedir(dirp);
3646 Py_END_ALLOW_THREADS
3647 }
3648
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003650} /* end of _posix_listdir */
3651#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003652
Larry Hastings2f936352014-08-05 14:04:04 +10003653
3654/*[clinic input]
3655os.listdir
3656
3657 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3658
3659Return a list containing the names of the files in the directory.
3660
BNMetrics08026b12018-11-02 17:56:25 +00003661path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003662 the filenames returned will also be bytes; in all other circumstances
3663 the filenames returned will be str.
3664If path is None, uses the path='.'.
3665On some platforms, path may also be specified as an open file descriptor;\
3666 the file descriptor must refer to a directory.
3667 If this functionality is unavailable, using it raises NotImplementedError.
3668
3669The list is in arbitrary order. It does not include the special
3670entries '.' and '..' even if they are present in the directory.
3671
3672
3673[clinic start generated code]*/
3674
Larry Hastings2f936352014-08-05 14:04:04 +10003675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003676os_listdir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +00003677/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003678{
3679#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3680 return _listdir_windows_no_opendir(path, NULL);
3681#else
3682 return _posix_listdir(path, NULL);
3683#endif
3684}
3685
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003686#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003687/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003688/*[clinic input]
3689os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003690
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003691 path: path_t
3692 /
3693
3694[clinic start generated code]*/
3695
3696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003697os__getfullpathname_impl(PyObject *module, path_t *path)
3698/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003699{
Steve Dowercc16be82016-09-08 10:35:16 -07003700 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3701 wchar_t *wtemp;
3702 DWORD result;
3703 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003704
Steve Dowercc16be82016-09-08 10:35:16 -07003705 result = GetFullPathNameW(path->wide,
3706 Py_ARRAY_LENGTH(woutbuf),
3707 woutbuf, &wtemp);
3708 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3709 woutbufp = PyMem_New(wchar_t, result);
3710 if (!woutbufp)
3711 return PyErr_NoMemory();
3712 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 }
Steve Dowercc16be82016-09-08 10:35:16 -07003714 if (result) {
3715 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3716 if (path->narrow)
3717 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3718 } else
3719 v = win32_error_object("GetFullPathNameW", path->object);
3720 if (woutbufp != woutbuf)
3721 PyMem_Free(woutbufp);
3722 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003723}
Brian Curtind40e6f72010-07-08 21:39:08 +00003724
Brian Curtind25aef52011-06-13 15:16:04 -05003725
Larry Hastings2f936352014-08-05 14:04:04 +10003726/*[clinic input]
3727os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003728
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003729 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003730 /
3731
3732A helper function for samepath on windows.
3733[clinic start generated code]*/
3734
Larry Hastings2f936352014-08-05 14:04:04 +10003735static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003736os__getfinalpathname_impl(PyObject *module, path_t *path)
3737/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003738{
3739 HANDLE hFile;
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003740 wchar_t buf[MAXPATHLEN], *target_path = buf;
3741 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003742 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003743 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003744
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003745 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003746 hFile = CreateFileW(
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003747 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003748 0, /* desired access */
3749 0, /* share mode */
3750 NULL, /* security attributes */
3751 OPEN_EXISTING,
3752 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3753 FILE_FLAG_BACKUP_SEMANTICS,
3754 NULL);
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003755 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003756
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003757 if (hFile == INVALID_HANDLE_VALUE) {
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003758 return win32_error_object("CreateFileW", path->object);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003759 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003760
3761 /* We have a good handle to the target, use it to determine the
3762 target path name. */
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003763 while (1) {
3764 Py_BEGIN_ALLOW_THREADS
3765 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3766 buf_size, VOLUME_NAME_DOS);
3767 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003768
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003769 if (!result_length) {
3770 result = win32_error_object("GetFinalPathNameByHandleW",
3771 path->object);
3772 goto cleanup;
3773 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003774
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003775 if (result_length < buf_size) {
3776 break;
3777 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003778
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003779 wchar_t *tmp;
3780 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3781 result_length * sizeof(*tmp));
3782 if (!tmp) {
3783 result = PyErr_NoMemory();
3784 goto cleanup;
3785 }
3786
3787 buf_size = result_length;
3788 target_path = tmp;
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003789 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003790
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003791 result = PyUnicode_FromWideChar(target_path, result_length);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003792 if (path->narrow)
3793 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003794
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003795cleanup:
3796 if (target_path != buf) {
3797 PyMem_Free(target_path);
3798 }
3799 CloseHandle(hFile);
3800 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003801}
Brian Curtin62857742010-09-06 17:07:27 +00003802
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003803/*[clinic input]
3804os._isdir
3805
3806 path: path_t
3807 /
3808
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003809Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003810[clinic start generated code]*/
3811
Brian Curtin9c669cc2011-06-08 18:17:18 -05003812static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003813os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003814/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003815{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003816 DWORD attributes;
3817
Steve Dowerb22a6772016-07-17 20:49:38 -07003818 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003819 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003820 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003821
Brian Curtin9c669cc2011-06-08 18:17:18 -05003822 if (attributes == INVALID_FILE_ATTRIBUTES)
3823 Py_RETURN_FALSE;
3824
Brian Curtin9c669cc2011-06-08 18:17:18 -05003825 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3826 Py_RETURN_TRUE;
3827 else
3828 Py_RETURN_FALSE;
3829}
Tim Golden6b528062013-08-01 12:44:00 +01003830
Tim Golden6b528062013-08-01 12:44:00 +01003831
Larry Hastings2f936352014-08-05 14:04:04 +10003832/*[clinic input]
3833os._getvolumepathname
3834
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003835 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003836
3837A helper function for ismount on Win32.
3838[clinic start generated code]*/
3839
Larry Hastings2f936352014-08-05 14:04:04 +10003840static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003841os__getvolumepathname_impl(PyObject *module, path_t *path)
3842/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003843{
3844 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003845 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003846 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003847 BOOL ret;
3848
Tim Golden6b528062013-08-01 12:44:00 +01003849 /* Volume path should be shorter than entire path */
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003850 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003851
Victor Stinner850a18e2017-10-24 16:53:32 -07003852 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003853 PyErr_SetString(PyExc_OverflowError, "path too long");
3854 return NULL;
3855 }
3856
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003857 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003858 if (mountpath == NULL)
3859 return PyErr_NoMemory();
3860
3861 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003862 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003863 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003864 Py_END_ALLOW_THREADS
3865
3866 if (!ret) {
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003867 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003868 goto exit;
3869 }
3870 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003871 if (path->narrow)
3872 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003873
3874exit:
3875 PyMem_Free(mountpath);
3876 return result;
3877}
Tim Golden6b528062013-08-01 12:44:00 +01003878
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003879#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003880
Larry Hastings2f936352014-08-05 14:04:04 +10003881
3882/*[clinic input]
3883os.mkdir
3884
3885 path : path_t
3886
3887 mode: int = 0o777
3888
3889 *
3890
3891 dir_fd : dir_fd(requires='mkdirat') = None
3892
3893# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3894
3895Create a directory.
3896
3897If dir_fd is not None, it should be a file descriptor open to a directory,
3898 and path should be relative; path will then be relative to that directory.
3899dir_fd may not be implemented on your platform.
3900 If it is unavailable, using it will raise a NotImplementedError.
3901
3902The mode argument is ignored on Windows.
3903[clinic start generated code]*/
3904
Larry Hastings2f936352014-08-05 14:04:04 +10003905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003906os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3907/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003908{
3909 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003910
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003911#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003912 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003913 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003914 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003915
Larry Hastings2f936352014-08-05 14:04:04 +10003916 if (!result)
3917 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003918#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003920#if HAVE_MKDIRAT
3921 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003922 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003923 else
3924#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003925#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003926 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003927#else
Larry Hastings2f936352014-08-05 14:04:04 +10003928 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003929#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003930 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003931 if (result < 0)
3932 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003933#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003934 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003935}
3936
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003937
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003938/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3939#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003940#include <sys/resource.h>
3941#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003942
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003943
3944#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003945/*[clinic input]
3946os.nice
3947
3948 increment: int
3949 /
3950
3951Add increment to the priority of process and return the new priority.
3952[clinic start generated code]*/
3953
Larry Hastings2f936352014-08-05 14:04:04 +10003954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003955os_nice_impl(PyObject *module, int increment)
3956/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003957{
3958 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003959
Victor Stinner8c62be82010-05-06 00:08:46 +00003960 /* There are two flavours of 'nice': one that returns the new
3961 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003962 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003964
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 If we are of the nice family that returns the new priority, we
3966 need to clear errno before the call, and check if errno is filled
3967 before calling posix_error() on a returnvalue of -1, because the
3968 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003969
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 errno = 0;
3971 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003972#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003973 if (value == 0)
3974 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003975#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003976 if (value == -1 && errno != 0)
3977 /* either nice() or getpriority() returned an error */
3978 return posix_error();
3979 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003980}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003981#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003982
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003983
3984#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003985/*[clinic input]
3986os.getpriority
3987
3988 which: int
3989 who: int
3990
3991Return program scheduling priority.
3992[clinic start generated code]*/
3993
Larry Hastings2f936352014-08-05 14:04:04 +10003994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003995os_getpriority_impl(PyObject *module, int which, int who)
3996/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003997{
3998 int retval;
3999
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004000 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004001 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004002 if (errno != 0)
4003 return posix_error();
4004 return PyLong_FromLong((long)retval);
4005}
4006#endif /* HAVE_GETPRIORITY */
4007
4008
4009#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004010/*[clinic input]
4011os.setpriority
4012
4013 which: int
4014 who: int
4015 priority: int
4016
4017Set program scheduling priority.
4018[clinic start generated code]*/
4019
Larry Hastings2f936352014-08-05 14:04:04 +10004020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004021os_setpriority_impl(PyObject *module, int which, int who, int priority)
4022/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004023{
4024 int retval;
4025
4026 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004027 if (retval == -1)
4028 return posix_error();
4029 Py_RETURN_NONE;
4030}
4031#endif /* HAVE_SETPRIORITY */
4032
4033
Barry Warsaw53699e91996-12-10 23:23:01 +00004034static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004035internal_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 +00004036{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004037 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004038 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004039
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004040#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004041 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004042 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004043#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004044 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004045#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4048 (dst_dir_fd != DEFAULT_DIR_FD);
4049#ifndef HAVE_RENAMEAT
4050 if (dir_fd_specified) {
4051 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004052 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004053 }
4054#endif
4055
Larry Hastings9cf065c2012-06-22 16:30:09 -07004056#ifdef MS_WINDOWS
4057 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004058 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059 Py_END_ALLOW_THREADS
4060
Larry Hastings2f936352014-08-05 14:04:04 +10004061 if (!result)
4062 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004063
4064#else
Steve Dowercc16be82016-09-08 10:35:16 -07004065 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4066 PyErr_Format(PyExc_ValueError,
4067 "%s: src and dst must be the same type", function_name);
4068 return NULL;
4069 }
4070
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071 Py_BEGIN_ALLOW_THREADS
4072#ifdef HAVE_RENAMEAT
4073 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004074 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004075 else
4076#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004077 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078 Py_END_ALLOW_THREADS
4079
Larry Hastings2f936352014-08-05 14:04:04 +10004080 if (result)
4081 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004082#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004083 Py_RETURN_NONE;
4084}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004085
Larry Hastings2f936352014-08-05 14:04:04 +10004086
4087/*[clinic input]
4088os.rename
4089
4090 src : path_t
4091 dst : path_t
4092 *
4093 src_dir_fd : dir_fd = None
4094 dst_dir_fd : dir_fd = None
4095
4096Rename a file or directory.
4097
4098If either src_dir_fd or dst_dir_fd is not None, it should be a file
4099 descriptor open to a directory, and the respective path string (src or dst)
4100 should be relative; the path will then be relative to that directory.
4101src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4102 If they are unavailable, using them will raise a NotImplementedError.
4103[clinic start generated code]*/
4104
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004105static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004106os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004107 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004108/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004109{
Larry Hastings2f936352014-08-05 14:04:04 +10004110 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004111}
4112
Larry Hastings2f936352014-08-05 14:04:04 +10004113
4114/*[clinic input]
4115os.replace = os.rename
4116
4117Rename a file or directory, overwriting the destination.
4118
4119If either src_dir_fd or dst_dir_fd is not None, it should be a file
4120 descriptor open to a directory, and the respective path string (src or dst)
4121 should be relative; the path will then be relative to that directory.
4122src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4123 If they are unavailable, using them will raise a NotImplementedError."
4124[clinic start generated code]*/
4125
Larry Hastings2f936352014-08-05 14:04:04 +10004126static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004127os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4128 int dst_dir_fd)
4129/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004130{
4131 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4132}
4133
4134
4135/*[clinic input]
4136os.rmdir
4137
4138 path: path_t
4139 *
4140 dir_fd: dir_fd(requires='unlinkat') = None
4141
4142Remove a directory.
4143
4144If dir_fd is not None, it should be a file descriptor open to a directory,
4145 and path should be relative; path will then be relative to that directory.
4146dir_fd may not be implemented on your platform.
4147 If it is unavailable, using it will raise a NotImplementedError.
4148[clinic start generated code]*/
4149
Larry Hastings2f936352014-08-05 14:04:04 +10004150static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004151os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4152/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004153{
4154 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004155
4156 Py_BEGIN_ALLOW_THREADS
4157#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004158 /* Windows, success=1, UNIX, success=0 */
4159 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004160#else
4161#ifdef HAVE_UNLINKAT
4162 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004163 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004164 else
4165#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004166 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004167#endif
4168 Py_END_ALLOW_THREADS
4169
Larry Hastings2f936352014-08-05 14:04:04 +10004170 if (result)
4171 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004172
Larry Hastings2f936352014-08-05 14:04:04 +10004173 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004174}
4175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004176
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004177#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004178#ifdef MS_WINDOWS
4179/*[clinic input]
4180os.system -> long
4181
4182 command: Py_UNICODE
4183
4184Execute the command in a subshell.
4185[clinic start generated code]*/
4186
Larry Hastings2f936352014-08-05 14:04:04 +10004187static long
Serhiy Storchaka45a7b762018-12-14 11:56:48 +02004188os_system_impl(PyObject *module, const Py_UNICODE *command)
4189/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004190{
4191 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004193 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004194 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004195 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004196 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004197 return result;
4198}
4199#else /* MS_WINDOWS */
4200/*[clinic input]
4201os.system -> long
4202
4203 command: FSConverter
4204
4205Execute the command in a subshell.
4206[clinic start generated code]*/
4207
Larry Hastings2f936352014-08-05 14:04:04 +10004208static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004209os_system_impl(PyObject *module, PyObject *command)
4210/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004211{
4212 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004213 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004214 Py_BEGIN_ALLOW_THREADS
4215 result = system(bytes);
4216 Py_END_ALLOW_THREADS
4217 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004218}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004219#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004220#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004222
Larry Hastings2f936352014-08-05 14:04:04 +10004223/*[clinic input]
4224os.umask
4225
4226 mask: int
4227 /
4228
4229Set the current numeric umask and return the previous umask.
4230[clinic start generated code]*/
4231
Larry Hastings2f936352014-08-05 14:04:04 +10004232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004233os_umask_impl(PyObject *module, int mask)
4234/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004235{
4236 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004237 if (i < 0)
4238 return posix_error();
4239 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004240}
4241
Brian Curtind40e6f72010-07-08 21:39:08 +00004242#ifdef MS_WINDOWS
4243
4244/* override the default DeleteFileW behavior so that directory
4245symlinks can be removed with this function, the same as with
4246Unix symlinks */
4247BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4248{
4249 WIN32_FILE_ATTRIBUTE_DATA info;
4250 WIN32_FIND_DATAW find_data;
4251 HANDLE find_data_handle;
4252 int is_directory = 0;
4253 int is_link = 0;
4254
4255 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4256 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004257
Brian Curtind40e6f72010-07-08 21:39:08 +00004258 /* Get WIN32_FIND_DATA structure for the path to determine if
4259 it is a symlink */
4260 if(is_directory &&
4261 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4262 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4263
4264 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004265 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4266 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4267 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4268 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004269 FindClose(find_data_handle);
4270 }
4271 }
4272 }
4273
4274 if (is_directory && is_link)
4275 return RemoveDirectoryW(lpFileName);
4276
4277 return DeleteFileW(lpFileName);
4278}
4279#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004281
Larry Hastings2f936352014-08-05 14:04:04 +10004282/*[clinic input]
4283os.unlink
4284
4285 path: path_t
4286 *
4287 dir_fd: dir_fd(requires='unlinkat')=None
4288
4289Remove a file (same as remove()).
4290
4291If dir_fd is not None, it should be a file descriptor open to a directory,
4292 and path should be relative; path will then be relative to that directory.
4293dir_fd may not be implemented on your platform.
4294 If it is unavailable, using it will raise a NotImplementedError.
4295
4296[clinic start generated code]*/
4297
Larry Hastings2f936352014-08-05 14:04:04 +10004298static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004299os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4300/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004301{
4302 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004303
4304 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004305 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004307 /* Windows, success=1, UNIX, success=0 */
4308 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004309#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004310#ifdef HAVE_UNLINKAT
4311 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004312 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004313 else
4314#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004315 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004316#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004317 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318 Py_END_ALLOW_THREADS
4319
Larry Hastings2f936352014-08-05 14:04:04 +10004320 if (result)
4321 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004322
Larry Hastings2f936352014-08-05 14:04:04 +10004323 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004324}
4325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004326
Larry Hastings2f936352014-08-05 14:04:04 +10004327/*[clinic input]
4328os.remove = os.unlink
4329
4330Remove a file (same as unlink()).
4331
4332If dir_fd is not None, it should be a file descriptor open to a directory,
4333 and path should be relative; path will then be relative to that directory.
4334dir_fd may not be implemented on your platform.
4335 If it is unavailable, using it will raise a NotImplementedError.
4336[clinic start generated code]*/
4337
Larry Hastings2f936352014-08-05 14:04:04 +10004338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004339os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4340/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004341{
4342 return os_unlink_impl(module, path, dir_fd);
4343}
4344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004345
Larry Hastings605a62d2012-06-24 04:33:36 -07004346static PyStructSequence_Field uname_result_fields[] = {
4347 {"sysname", "operating system name"},
4348 {"nodename", "name of machine on network (implementation-defined)"},
4349 {"release", "operating system release"},
4350 {"version", "operating system version"},
4351 {"machine", "hardware identifier"},
4352 {NULL}
4353};
4354
4355PyDoc_STRVAR(uname_result__doc__,
4356"uname_result: Result from os.uname().\n\n\
4357This object may be accessed either as a tuple of\n\
4358 (sysname, nodename, release, version, machine),\n\
4359or via the attributes sysname, nodename, release, version, and machine.\n\
4360\n\
4361See os.uname for more information.");
4362
4363static PyStructSequence_Desc uname_result_desc = {
4364 "uname_result", /* name */
4365 uname_result__doc__, /* doc */
4366 uname_result_fields,
4367 5
4368};
4369
4370static PyTypeObject UnameResultType;
4371
4372
4373#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004374/*[clinic input]
4375os.uname
4376
4377Return an object identifying the current operating system.
4378
4379The object behaves like a named tuple with the following fields:
4380 (sysname, nodename, release, version, machine)
4381
4382[clinic start generated code]*/
4383
Larry Hastings2f936352014-08-05 14:04:04 +10004384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004385os_uname_impl(PyObject *module)
4386/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004387{
Victor Stinner8c62be82010-05-06 00:08:46 +00004388 struct utsname u;
4389 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004390 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004391
Victor Stinner8c62be82010-05-06 00:08:46 +00004392 Py_BEGIN_ALLOW_THREADS
4393 res = uname(&u);
4394 Py_END_ALLOW_THREADS
4395 if (res < 0)
4396 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004397
4398 value = PyStructSequence_New(&UnameResultType);
4399 if (value == NULL)
4400 return NULL;
4401
4402#define SET(i, field) \
4403 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004404 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004405 if (!o) { \
4406 Py_DECREF(value); \
4407 return NULL; \
4408 } \
4409 PyStructSequence_SET_ITEM(value, i, o); \
4410 } \
4411
4412 SET(0, u.sysname);
4413 SET(1, u.nodename);
4414 SET(2, u.release);
4415 SET(3, u.version);
4416 SET(4, u.machine);
4417
4418#undef SET
4419
4420 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004421}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004422#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004423
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004424
Larry Hastings9cf065c2012-06-22 16:30:09 -07004425
4426typedef struct {
4427 int now;
4428 time_t atime_s;
4429 long atime_ns;
4430 time_t mtime_s;
4431 long mtime_ns;
4432} utime_t;
4433
4434/*
Victor Stinner484df002014-10-09 13:52:31 +02004435 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004436 * they also intentionally leak the declaration of a pointer named "time"
4437 */
4438#define UTIME_TO_TIMESPEC \
4439 struct timespec ts[2]; \
4440 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004441 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004442 time = NULL; \
4443 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004444 ts[0].tv_sec = ut->atime_s; \
4445 ts[0].tv_nsec = ut->atime_ns; \
4446 ts[1].tv_sec = ut->mtime_s; \
4447 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004448 time = ts; \
4449 } \
4450
4451#define UTIME_TO_TIMEVAL \
4452 struct timeval tv[2]; \
4453 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004454 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004455 time = NULL; \
4456 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004457 tv[0].tv_sec = ut->atime_s; \
4458 tv[0].tv_usec = ut->atime_ns / 1000; \
4459 tv[1].tv_sec = ut->mtime_s; \
4460 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004461 time = tv; \
4462 } \
4463
4464#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004465 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004466 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004467 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468 time = NULL; \
4469 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004470 u.actime = ut->atime_s; \
4471 u.modtime = ut->mtime_s; \
4472 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473 }
4474
4475#define UTIME_TO_TIME_T \
4476 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004477 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004478 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004479 time = NULL; \
4480 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004481 timet[0] = ut->atime_s; \
4482 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004483 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484 } \
4485
4486
Victor Stinner528a9ab2015-09-03 21:30:26 +02004487#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004488
4489static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004490utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004491{
4492#ifdef HAVE_UTIMENSAT
4493 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4494 UTIME_TO_TIMESPEC;
4495 return utimensat(dir_fd, path, time, flags);
4496#elif defined(HAVE_FUTIMESAT)
4497 UTIME_TO_TIMEVAL;
4498 /*
4499 * follow_symlinks will never be false here;
4500 * we only allow !follow_symlinks and dir_fd together
4501 * if we have utimensat()
4502 */
4503 assert(follow_symlinks);
4504 return futimesat(dir_fd, path, time);
4505#endif
4506}
4507
Larry Hastings2f936352014-08-05 14:04:04 +10004508 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4509#else
4510 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004511#endif
4512
Victor Stinner528a9ab2015-09-03 21:30:26 +02004513#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514
4515static int
Victor Stinner484df002014-10-09 13:52:31 +02004516utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517{
4518#ifdef HAVE_FUTIMENS
4519 UTIME_TO_TIMESPEC;
4520 return futimens(fd, time);
4521#else
4522 UTIME_TO_TIMEVAL;
4523 return futimes(fd, time);
4524#endif
4525}
4526
Larry Hastings2f936352014-08-05 14:04:04 +10004527 #define PATH_UTIME_HAVE_FD 1
4528#else
4529 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004530#endif
4531
Victor Stinner5ebae872015-09-22 01:29:33 +02004532#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4533# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4534#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535
Victor Stinner4552ced2015-09-21 22:37:15 +02004536#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004537
4538static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004539utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540{
4541#ifdef HAVE_UTIMENSAT
4542 UTIME_TO_TIMESPEC;
4543 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4544#else
4545 UTIME_TO_TIMEVAL;
4546 return lutimes(path, time);
4547#endif
4548}
4549
4550#endif
4551
4552#ifndef MS_WINDOWS
4553
4554static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004555utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556{
4557#ifdef HAVE_UTIMENSAT
4558 UTIME_TO_TIMESPEC;
4559 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4560#elif defined(HAVE_UTIMES)
4561 UTIME_TO_TIMEVAL;
4562 return utimes(path, time);
4563#elif defined(HAVE_UTIME_H)
4564 UTIME_TO_UTIMBUF;
4565 return utime(path, time);
4566#else
4567 UTIME_TO_TIME_T;
4568 return utime(path, time);
4569#endif
4570}
4571
4572#endif
4573
Larry Hastings76ad59b2012-05-03 00:30:07 -07004574static int
4575split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4576{
4577 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004578 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004579 divmod = PyNumber_Divmod(py_long, billion);
4580 if (!divmod)
4581 goto exit;
Miss Islington (bot)329ea4e2018-09-12 12:46:30 -07004582 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4583 PyErr_Format(PyExc_TypeError,
4584 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4585 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4586 goto exit;
4587 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004588 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4589 if ((*s == -1) && PyErr_Occurred())
4590 goto exit;
4591 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004592 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004593 goto exit;
4594
4595 result = 1;
4596exit:
4597 Py_XDECREF(divmod);
4598 return result;
4599}
4600
Larry Hastings2f936352014-08-05 14:04:04 +10004601
4602/*[clinic input]
4603os.utime
4604
4605 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4606 times: object = NULL
4607 *
4608 ns: object = NULL
4609 dir_fd: dir_fd(requires='futimensat') = None
4610 follow_symlinks: bool=True
4611
Martin Panter0ff89092015-09-09 01:56:53 +00004612# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004613
4614Set the access and modified time of path.
4615
4616path may always be specified as a string.
4617On some platforms, path may also be specified as an open file descriptor.
4618 If this functionality is unavailable, using it raises an exception.
4619
4620If times is not None, it must be a tuple (atime, mtime);
4621 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004622If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004623 atime_ns and mtime_ns should be expressed as integer nanoseconds
4624 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004625If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004626Specifying tuples for both times and ns is an error.
4627
4628If dir_fd is not None, it should be a file descriptor open to a directory,
4629 and path should be relative; path will then be relative to that directory.
4630If follow_symlinks is False, and the last element of the path is a symbolic
4631 link, utime will modify the symbolic link itself instead of the file the
4632 link points to.
4633It is an error to use dir_fd or follow_symlinks when specifying path
4634 as an open file descriptor.
4635dir_fd and follow_symlinks may not be available on your platform.
4636 If they are unavailable, using them will raise a NotImplementedError.
4637
4638[clinic start generated code]*/
4639
Larry Hastings2f936352014-08-05 14:04:04 +10004640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004641os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4642 int dir_fd, int follow_symlinks)
4643/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004644{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645#ifdef MS_WINDOWS
4646 HANDLE hFile;
4647 FILETIME atime, mtime;
4648#else
4649 int result;
4650#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004651
Larry Hastings2f936352014-08-05 14:04:04 +10004652 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653
Christian Heimesb3c87242013-08-01 00:08:16 +02004654 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004655
Larry Hastings9cf065c2012-06-22 16:30:09 -07004656 if (times && (times != Py_None) && ns) {
4657 PyErr_SetString(PyExc_ValueError,
4658 "utime: you may specify either 'times'"
4659 " or 'ns' but not both");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004660 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004661 }
4662
4663 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004664 time_t a_sec, m_sec;
4665 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004666 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004667 PyErr_SetString(PyExc_TypeError,
4668 "utime: 'times' must be either"
4669 " a tuple of two ints or None");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004670 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004671 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004672 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004673 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004674 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004675 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004676 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004677 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004678 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004679 utime.atime_s = a_sec;
4680 utime.atime_ns = a_nsec;
4681 utime.mtime_s = m_sec;
4682 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004683 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004684 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004685 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 PyErr_SetString(PyExc_TypeError,
4687 "utime: 'ns' must be a tuple of two ints");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004688 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004689 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004691 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004693 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 &utime.mtime_s, &utime.mtime_ns)) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004695 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004696 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 }
4698 else {
4699 /* times and ns are both None/unspecified. use "now". */
4700 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004701 }
4702
Victor Stinner4552ced2015-09-21 22:37:15 +02004703#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004704 if (follow_symlinks_specified("utime", follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004705 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004707
Larry Hastings2f936352014-08-05 14:04:04 +10004708 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4709 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4710 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004711 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004712
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713#if !defined(HAVE_UTIMENSAT)
4714 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004715 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 "utime: cannot use dir_fd and follow_symlinks "
4717 "together on this platform");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004718 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 }
4720#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004721
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004722#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004723 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004724 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4725 NULL, OPEN_EXISTING,
4726 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 Py_END_ALLOW_THREADS
4728 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004729 path_error(path);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004730 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004731 }
4732
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004734 GetSystemTimeAsFileTime(&mtime);
4735 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004737 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004738 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4739 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004740 }
4741 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4742 /* Avoid putting the file name into the error here,
4743 as that may confuse the user into believing that
4744 something is wrong with the file, when it also
4745 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004746 PyErr_SetFromWindowsErr(0);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004747 CloseHandle(hFile);
4748 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004749 }
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004750 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004751#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004753
Victor Stinner4552ced2015-09-21 22:37:15 +02004754#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004756 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004758#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759
Victor Stinner528a9ab2015-09-03 21:30:26 +02004760#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004762 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 else
4764#endif
4765
Victor Stinner528a9ab2015-09-03 21:30:26 +02004766#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004767 if (path->fd != -1)
4768 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 else
4770#endif
4771
Larry Hastings2f936352014-08-05 14:04:04 +10004772 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773
4774 Py_END_ALLOW_THREADS
4775
4776 if (result < 0) {
4777 /* see previous comment about not putting filename in error here */
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004778 posix_error();
4779 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004781
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004782#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004784 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004785}
4786
Guido van Rossum3b066191991-06-04 19:40:25 +00004787/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004788
Larry Hastings2f936352014-08-05 14:04:04 +10004789
4790/*[clinic input]
4791os._exit
4792
4793 status: int
4794
4795Exit to the system with specified status, without normal exit processing.
4796[clinic start generated code]*/
4797
Larry Hastings2f936352014-08-05 14:04:04 +10004798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004799os__exit_impl(PyObject *module, int status)
4800/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004801{
4802 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004803 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004804}
4805
Steve Dowercc16be82016-09-08 10:35:16 -07004806#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4807#define EXECV_CHAR wchar_t
4808#else
4809#define EXECV_CHAR char
4810#endif
4811
Martin v. Löwis114619e2002-10-07 06:44:21 +00004812#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4813static void
Steve Dowercc16be82016-09-08 10:35:16 -07004814free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004815{
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 Py_ssize_t i;
4817 for (i = 0; i < count; i++)
4818 PyMem_Free(array[i]);
4819 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004820}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004821
Berker Peksag81816462016-09-15 20:19:47 +03004822static int
4823fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004824{
Victor Stinner8c62be82010-05-06 00:08:46 +00004825 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004826 PyObject *ub;
4827 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004828#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004829 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004830 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004831 *out = PyUnicode_AsWideCharString(ub, &size);
4832 if (*out)
4833 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004834#else
Berker Peksag81816462016-09-15 20:19:47 +03004835 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004837 size = PyBytes_GET_SIZE(ub);
4838 *out = PyMem_Malloc(size + 1);
4839 if (*out) {
4840 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4841 result = 1;
4842 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004843 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004844#endif
Berker Peksag81816462016-09-15 20:19:47 +03004845 Py_DECREF(ub);
4846 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004847}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004848#endif
4849
Ross Lagerwall7807c352011-03-17 20:20:30 +02004850#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004851static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004852parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4853{
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 Py_ssize_t i, pos, envc;
4855 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004856 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004857 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004858
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 i = PyMapping_Size(env);
4860 if (i < 0)
4861 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004862 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 if (envlist == NULL) {
4864 PyErr_NoMemory();
4865 return NULL;
4866 }
4867 envc = 0;
4868 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004869 if (!keys)
4870 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004871 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004872 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 goto error;
4874 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4875 PyErr_Format(PyExc_TypeError,
4876 "env.keys() or env.values() is not a list");
4877 goto error;
4878 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004879
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 for (pos = 0; pos < i; pos++) {
4881 key = PyList_GetItem(keys, pos);
4882 val = PyList_GetItem(vals, pos);
4883 if (!key || !val)
4884 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004885
Berker Peksag81816462016-09-15 20:19:47 +03004886#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4887 if (!PyUnicode_FSDecoder(key, &key2))
4888 goto error;
4889 if (!PyUnicode_FSDecoder(val, &val2)) {
4890 Py_DECREF(key2);
4891 goto error;
4892 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004893 /* Search from index 1 because on Windows starting '=' is allowed for
4894 defining hidden environment variables. */
4895 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4896 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4897 {
4898 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004899 Py_DECREF(key2);
4900 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004901 goto error;
4902 }
Berker Peksag81816462016-09-15 20:19:47 +03004903 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4904#else
4905 if (!PyUnicode_FSConverter(key, &key2))
4906 goto error;
4907 if (!PyUnicode_FSConverter(val, &val2)) {
4908 Py_DECREF(key2);
4909 goto error;
4910 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004911 if (PyBytes_GET_SIZE(key2) == 0 ||
4912 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4913 {
4914 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004915 Py_DECREF(key2);
4916 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004917 goto error;
4918 }
Berker Peksag81816462016-09-15 20:19:47 +03004919 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4920 PyBytes_AS_STRING(val2));
4921#endif
4922 Py_DECREF(key2);
4923 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004924 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004926
4927 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4928 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 goto error;
4930 }
Berker Peksag81816462016-09-15 20:19:47 +03004931
Steve Dowercc16be82016-09-08 10:35:16 -07004932 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 }
4934 Py_DECREF(vals);
4935 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004936
Victor Stinner8c62be82010-05-06 00:08:46 +00004937 envlist[envc] = 0;
4938 *envc_ptr = envc;
4939 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004940
4941error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 Py_XDECREF(keys);
4943 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004944 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004946}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004947
Steve Dowercc16be82016-09-08 10:35:16 -07004948static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949parse_arglist(PyObject* argv, Py_ssize_t *argc)
4950{
4951 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004952 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004953 if (argvlist == NULL) {
4954 PyErr_NoMemory();
4955 return NULL;
4956 }
4957 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004958 PyObject* item = PySequence_ITEM(argv, i);
4959 if (item == NULL)
4960 goto fail;
4961 if (!fsconvert_strdup(item, &argvlist[i])) {
4962 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963 goto fail;
4964 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004965 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004966 }
4967 argvlist[*argc] = NULL;
4968 return argvlist;
4969fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004970 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004971 free_string_array(argvlist, *argc);
4972 return NULL;
4973}
Steve Dowercc16be82016-09-08 10:35:16 -07004974
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975#endif
4976
Larry Hastings2f936352014-08-05 14:04:04 +10004977
Ross Lagerwall7807c352011-03-17 20:20:30 +02004978#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004979/*[clinic input]
4980os.execv
4981
Steve Dowercc16be82016-09-08 10:35:16 -07004982 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004983 Path of executable file.
4984 argv: object
4985 Tuple or list of strings.
4986 /
4987
4988Execute an executable path with arguments, replacing current process.
4989[clinic start generated code]*/
4990
Larry Hastings2f936352014-08-05 14:04:04 +10004991static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004992os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4993/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004994{
Steve Dowercc16be82016-09-08 10:35:16 -07004995 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004996 Py_ssize_t argc;
4997
4998 /* execv has two arguments: (path, argv), where
4999 argv is a list or tuple of strings. */
5000
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5002 PyErr_SetString(PyExc_TypeError,
5003 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005004 return NULL;
5005 }
5006 argc = PySequence_Size(argv);
5007 if (argc < 1) {
5008 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005009 return NULL;
5010 }
5011
5012 argvlist = parse_arglist(argv, &argc);
5013 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014 return NULL;
5015 }
Steve Dowerbce26262016-11-19 19:17:26 -08005016 if (!argvlist[0][0]) {
5017 PyErr_SetString(PyExc_ValueError,
5018 "execv() arg 2 first element cannot be empty");
5019 free_string_array(argvlist, argc);
5020 return NULL;
5021 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005022
Steve Dowerbce26262016-11-19 19:17:26 -08005023 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005024#ifdef HAVE_WEXECV
5025 _wexecv(path->wide, argvlist);
5026#else
5027 execv(path->narrow, argvlist);
5028#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005029 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030
5031 /* If we get here it's definitely an error */
5032
5033 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005034 return posix_error();
5035}
5036
Larry Hastings2f936352014-08-05 14:04:04 +10005037
5038/*[clinic input]
5039os.execve
5040
5041 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5042 Path of executable file.
5043 argv: object
5044 Tuple or list of strings.
5045 env: object
5046 Dictionary of strings mapping to strings.
5047
5048Execute an executable path with arguments, replacing current process.
5049[clinic start generated code]*/
5050
Larry Hastings2f936352014-08-05 14:04:04 +10005051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005052os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5053/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005054{
Steve Dowercc16be82016-09-08 10:35:16 -07005055 EXECV_CHAR **argvlist = NULL;
5056 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005057 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005058
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 /* execve has three arguments: (path, argv, env), where
5060 argv is a list or tuple of strings and env is a dictionary
5061 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005062
Ross Lagerwall7807c352011-03-17 20:20:30 +02005063 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005065 "execve: argv must be a tuple or list");
5066 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005068 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005069 if (argc < 1) {
5070 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5071 return NULL;
5072 }
5073
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 if (!PyMapping_Check(env)) {
5075 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005076 "execve: environment must be a mapping object");
5077 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005079
Ross Lagerwall7807c352011-03-17 20:20:30 +02005080 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005082 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 }
Steve Dowerbce26262016-11-19 19:17:26 -08005084 if (!argvlist[0][0]) {
5085 PyErr_SetString(PyExc_ValueError,
5086 "execve: argv first element cannot be empty");
5087 goto fail;
5088 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005089
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 envlist = parse_envlist(env, &envc);
5091 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005092 goto fail;
5093
Steve Dowerbce26262016-11-19 19:17:26 -08005094 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005095#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005096 if (path->fd > -1)
5097 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005098 else
5099#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005100#ifdef HAVE_WEXECV
5101 _wexecve(path->wide, argvlist, envlist);
5102#else
Larry Hastings2f936352014-08-05 14:04:04 +10005103 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005104#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005105 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005106
5107 /* If we get here it's definitely an error */
5108
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07005109 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110
Steve Dowercc16be82016-09-08 10:35:16 -07005111 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005112 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005113 if (argvlist)
5114 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 return NULL;
5116}
Steve Dowercc16be82016-09-08 10:35:16 -07005117
Larry Hastings9cf065c2012-06-22 16:30:09 -07005118#endif /* HAVE_EXECV */
5119
Steve Dowercc16be82016-09-08 10:35:16 -07005120#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005121/*[clinic input]
5122os.spawnv
5123
5124 mode: int
5125 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005126 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005127 Path of executable file.
5128 argv: object
5129 Tuple or list of strings.
5130 /
5131
5132Execute the program specified by path in a new process.
5133[clinic start generated code]*/
5134
Larry Hastings2f936352014-08-05 14:04:04 +10005135static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005136os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5137/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005138{
Steve Dowercc16be82016-09-08 10:35:16 -07005139 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005140 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005142 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005144
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 /* spawnv has three arguments: (mode, path, argv), where
5146 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 if (PyList_Check(argv)) {
5149 argc = PyList_Size(argv);
5150 getitem = PyList_GetItem;
5151 }
5152 else if (PyTuple_Check(argv)) {
5153 argc = PyTuple_Size(argv);
5154 getitem = PyTuple_GetItem;
5155 }
5156 else {
5157 PyErr_SetString(PyExc_TypeError,
5158 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 return NULL;
5160 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005161 if (argc == 0) {
5162 PyErr_SetString(PyExc_ValueError,
5163 "spawnv() arg 2 cannot be empty");
5164 return NULL;
5165 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005166
Steve Dowercc16be82016-09-08 10:35:16 -07005167 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 return PyErr_NoMemory();
5170 }
5171 for (i = 0; i < argc; i++) {
5172 if (!fsconvert_strdup((*getitem)(argv, i),
5173 &argvlist[i])) {
5174 free_string_array(argvlist, i);
5175 PyErr_SetString(
5176 PyExc_TypeError,
5177 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 return NULL;
5179 }
Steve Dower93ff8722016-11-19 19:03:54 -08005180 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005181 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005182 PyErr_SetString(
5183 PyExc_ValueError,
5184 "spawnv() arg 2 first element cannot be empty");
5185 return NULL;
5186 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 }
5188 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005189
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 if (mode == _OLD_P_OVERLAY)
5191 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005192
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005194 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005195#ifdef HAVE_WSPAWNV
5196 spawnval = _wspawnv(mode, path->wide, argvlist);
5197#else
5198 spawnval = _spawnv(mode, path->narrow, argvlist);
5199#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005200 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 if (spawnval == -1)
5206 return posix_error();
5207 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005208 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005209}
5210
Larry Hastings2f936352014-08-05 14:04:04 +10005211/*[clinic input]
5212os.spawnve
5213
5214 mode: int
5215 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005216 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005217 Path of executable file.
5218 argv: object
5219 Tuple or list of strings.
5220 env: object
5221 Dictionary of strings mapping to strings.
5222 /
5223
5224Execute the program specified by path in a new process.
5225[clinic start generated code]*/
5226
Larry Hastings2f936352014-08-05 14:04:04 +10005227static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005228os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005229 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005230/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005231{
Steve Dowercc16be82016-09-08 10:35:16 -07005232 EXECV_CHAR **argvlist;
5233 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005234 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005235 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005236 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005237 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005238 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005239
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 /* spawnve has four arguments: (mode, path, argv, env), where
5241 argv is a list or tuple of strings and env is a dictionary
5242 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005243
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 if (PyList_Check(argv)) {
5245 argc = PyList_Size(argv);
5246 getitem = PyList_GetItem;
5247 }
5248 else if (PyTuple_Check(argv)) {
5249 argc = PyTuple_Size(argv);
5250 getitem = PyTuple_GetItem;
5251 }
5252 else {
5253 PyErr_SetString(PyExc_TypeError,
5254 "spawnve() arg 2 must be a tuple or list");
5255 goto fail_0;
5256 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005257 if (argc == 0) {
5258 PyErr_SetString(PyExc_ValueError,
5259 "spawnve() arg 2 cannot be empty");
5260 goto fail_0;
5261 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005262 if (!PyMapping_Check(env)) {
5263 PyErr_SetString(PyExc_TypeError,
5264 "spawnve() arg 3 must be a mapping object");
5265 goto fail_0;
5266 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005267
Steve Dowercc16be82016-09-08 10:35:16 -07005268 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005269 if (argvlist == NULL) {
5270 PyErr_NoMemory();
5271 goto fail_0;
5272 }
5273 for (i = 0; i < argc; i++) {
5274 if (!fsconvert_strdup((*getitem)(argv, i),
5275 &argvlist[i]))
5276 {
5277 lastarg = i;
5278 goto fail_1;
5279 }
Steve Dowerbce26262016-11-19 19:17:26 -08005280 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005281 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005282 PyErr_SetString(
5283 PyExc_ValueError,
5284 "spawnv() arg 2 first element cannot be empty");
5285 goto fail_1;
5286 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 }
5288 lastarg = argc;
5289 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 envlist = parse_envlist(env, &envc);
5292 if (envlist == NULL)
5293 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005294
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 if (mode == _OLD_P_OVERLAY)
5296 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005297
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005299 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005300#ifdef HAVE_WSPAWNV
5301 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5302#else
5303 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5304#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005305 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005307
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 if (spawnval == -1)
5309 (void) posix_error();
5310 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005311 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005312
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 while (--envc >= 0)
5314 PyMem_DEL(envlist[envc]);
5315 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005316 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005317 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005318 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005320}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005321
Guido van Rossuma1065681999-01-25 23:20:23 +00005322#endif /* HAVE_SPAWNV */
5323
5324
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005325#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005326
5327/* Helper function to validate arguments.
5328 Returns 0 on success. non-zero on failure with a TypeError raised.
5329 If obj is non-NULL it must be callable. */
5330static int
5331check_null_or_callable(PyObject *obj, const char* obj_name)
5332{
5333 if (obj && !PyCallable_Check(obj)) {
5334 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5335 obj_name, Py_TYPE(obj)->tp_name);
5336 return -1;
5337 }
5338 return 0;
5339}
5340
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005341/*[clinic input]
5342os.register_at_fork
5343
Gregory P. Smith163468a2017-05-29 10:03:41 -07005344 *
5345 before: object=NULL
5346 A callable to be called in the parent before the fork() syscall.
5347 after_in_child: object=NULL
5348 A callable to be called in the child after fork().
5349 after_in_parent: object=NULL
5350 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005351
Gregory P. Smith163468a2017-05-29 10:03:41 -07005352Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005353
Gregory P. Smith163468a2017-05-29 10:03:41 -07005354'before' callbacks are called in reverse order.
5355'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005356
5357[clinic start generated code]*/
5358
5359static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005360os_register_at_fork_impl(PyObject *module, PyObject *before,
5361 PyObject *after_in_child, PyObject *after_in_parent)
5362/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005363{
5364 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005365
Gregory P. Smith163468a2017-05-29 10:03:41 -07005366 if (!before && !after_in_child && !after_in_parent) {
5367 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5368 return NULL;
5369 }
5370 if (check_null_or_callable(before, "before") ||
5371 check_null_or_callable(after_in_child, "after_in_child") ||
5372 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005373 return NULL;
5374 }
5375 interp = PyThreadState_Get()->interp;
5376
Gregory P. Smith163468a2017-05-29 10:03:41 -07005377 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005378 return NULL;
5379 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005380 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005381 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005382 }
5383 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5384 return NULL;
5385 }
5386 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005387}
5388#endif /* HAVE_FORK */
5389
5390
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005391#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005392/*[clinic input]
5393os.fork1
5394
5395Fork a child process with a single multiplexed (i.e., not bound) thread.
5396
5397Return 0 to child process and PID of child to parent process.
5398[clinic start generated code]*/
5399
Larry Hastings2f936352014-08-05 14:04:04 +10005400static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005401os_fork1_impl(PyObject *module)
5402/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005403{
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005405
5406 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 pid = fork1();
5408 if (pid == 0) {
5409 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005410 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 } else {
5412 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005413 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 }
5415 if (pid == -1)
5416 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005417 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005418}
Larry Hastings2f936352014-08-05 14:04:04 +10005419#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005420
5421
Guido van Rossumad0ee831995-03-01 10:34:45 +00005422#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005423/*[clinic input]
5424os.fork
5425
5426Fork a child process.
5427
5428Return 0 to child process and PID of child to parent process.
5429[clinic start generated code]*/
5430
Larry Hastings2f936352014-08-05 14:04:04 +10005431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005432os_fork_impl(PyObject *module)
5433/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005434{
Victor Stinner8c62be82010-05-06 00:08:46 +00005435 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005436
5437 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 pid = fork();
5439 if (pid == 0) {
5440 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005441 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005442 } else {
5443 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005444 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005445 }
5446 if (pid == -1)
5447 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005448 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005449}
Larry Hastings2f936352014-08-05 14:04:04 +10005450#endif /* HAVE_FORK */
5451
Guido van Rossum85e3b011991-06-03 12:42:10 +00005452
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005453#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005454#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005455/*[clinic input]
5456os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005457
Larry Hastings2f936352014-08-05 14:04:04 +10005458 policy: int
5459
5460Get the maximum scheduling priority for policy.
5461[clinic start generated code]*/
5462
Larry Hastings2f936352014-08-05 14:04:04 +10005463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005464os_sched_get_priority_max_impl(PyObject *module, int policy)
5465/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005466{
5467 int max;
5468
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005469 max = sched_get_priority_max(policy);
5470 if (max < 0)
5471 return posix_error();
5472 return PyLong_FromLong(max);
5473}
5474
Larry Hastings2f936352014-08-05 14:04:04 +10005475
5476/*[clinic input]
5477os.sched_get_priority_min
5478
5479 policy: int
5480
5481Get the minimum scheduling priority for policy.
5482[clinic start generated code]*/
5483
Larry Hastings2f936352014-08-05 14:04:04 +10005484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005485os_sched_get_priority_min_impl(PyObject *module, int policy)
5486/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005487{
5488 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005489 if (min < 0)
5490 return posix_error();
5491 return PyLong_FromLong(min);
5492}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005493#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5494
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005495
Larry Hastings2f936352014-08-05 14:04:04 +10005496#ifdef HAVE_SCHED_SETSCHEDULER
5497/*[clinic input]
5498os.sched_getscheduler
5499 pid: pid_t
5500 /
5501
5502Get the scheduling policy for the process identifiedy by pid.
5503
5504Passing 0 for pid returns the scheduling policy for the calling process.
5505[clinic start generated code]*/
5506
Larry Hastings2f936352014-08-05 14:04:04 +10005507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005508os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5509/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005510{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005511 int policy;
5512
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005513 policy = sched_getscheduler(pid);
5514 if (policy < 0)
5515 return posix_error();
5516 return PyLong_FromLong(policy);
5517}
Larry Hastings2f936352014-08-05 14:04:04 +10005518#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005519
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005520
5521#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005522/*[clinic input]
5523class os.sched_param "PyObject *" "&SchedParamType"
5524
5525@classmethod
5526os.sched_param.__new__
5527
5528 sched_priority: object
5529 A scheduling parameter.
5530
5531Current has only one field: sched_priority");
5532[clinic start generated code]*/
5533
Larry Hastings2f936352014-08-05 14:04:04 +10005534static PyObject *
5535os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005536/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005537{
5538 PyObject *res;
5539
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005540 res = PyStructSequence_New(type);
5541 if (!res)
5542 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005543 Py_INCREF(sched_priority);
5544 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005545 return res;
5546}
5547
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005549PyDoc_VAR(os_sched_param__doc__);
5550
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005551static PyStructSequence_Field sched_param_fields[] = {
5552 {"sched_priority", "the scheduling priority"},
5553 {0}
5554};
5555
5556static PyStructSequence_Desc sched_param_desc = {
5557 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005558 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005559 sched_param_fields,
5560 1
5561};
5562
5563static int
5564convert_sched_param(PyObject *param, struct sched_param *res)
5565{
5566 long priority;
5567
5568 if (Py_TYPE(param) != &SchedParamType) {
5569 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5570 return 0;
5571 }
5572 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5573 if (priority == -1 && PyErr_Occurred())
5574 return 0;
5575 if (priority > INT_MAX || priority < INT_MIN) {
5576 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5577 return 0;
5578 }
5579 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5580 return 1;
5581}
Larry Hastings2f936352014-08-05 14:04:04 +10005582#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005583
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005584
5585#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005586/*[clinic input]
5587os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005588
Larry Hastings2f936352014-08-05 14:04:04 +10005589 pid: pid_t
5590 policy: int
5591 param: sched_param
5592 /
5593
5594Set the scheduling policy for the process identified by pid.
5595
5596If pid is 0, the calling process is changed.
5597param is an instance of sched_param.
5598[clinic start generated code]*/
5599
Larry Hastings2f936352014-08-05 14:04:04 +10005600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005601os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005602 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005603/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005604{
Jesus Cea9c822272011-09-10 01:40:52 +02005605 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005606 ** sched_setscheduler() returns 0 in Linux, but the previous
5607 ** scheduling policy under Solaris/Illumos, and others.
5608 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005609 */
Larry Hastings2f936352014-08-05 14:04:04 +10005610 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005611 return posix_error();
5612 Py_RETURN_NONE;
5613}
Larry Hastings2f936352014-08-05 14:04:04 +10005614#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005615
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005616
5617#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005618/*[clinic input]
5619os.sched_getparam
5620 pid: pid_t
5621 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005622
Larry Hastings2f936352014-08-05 14:04:04 +10005623Returns scheduling parameters for the process identified by pid.
5624
5625If pid is 0, returns parameters for the calling process.
5626Return value is an instance of sched_param.
5627[clinic start generated code]*/
5628
Larry Hastings2f936352014-08-05 14:04:04 +10005629static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005630os_sched_getparam_impl(PyObject *module, pid_t pid)
5631/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005632{
5633 struct sched_param param;
5634 PyObject *result;
5635 PyObject *priority;
5636
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637 if (sched_getparam(pid, &param))
5638 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005639 result = PyStructSequence_New(&SchedParamType);
5640 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005641 return NULL;
5642 priority = PyLong_FromLong(param.sched_priority);
5643 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005644 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005645 return NULL;
5646 }
Larry Hastings2f936352014-08-05 14:04:04 +10005647 PyStructSequence_SET_ITEM(result, 0, priority);
5648 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005649}
5650
Larry Hastings2f936352014-08-05 14:04:04 +10005651
5652/*[clinic input]
5653os.sched_setparam
5654 pid: pid_t
5655 param: sched_param
5656 /
5657
5658Set scheduling parameters for the process identified by pid.
5659
5660If pid is 0, sets parameters for the calling process.
5661param should be an instance of sched_param.
5662[clinic start generated code]*/
5663
Larry Hastings2f936352014-08-05 14:04:04 +10005664static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005665os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005666 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005667/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005668{
5669 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005670 return posix_error();
5671 Py_RETURN_NONE;
5672}
Larry Hastings2f936352014-08-05 14:04:04 +10005673#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005674
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005675
5676#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005677/*[clinic input]
5678os.sched_rr_get_interval -> double
5679 pid: pid_t
5680 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005681
Larry Hastings2f936352014-08-05 14:04:04 +10005682Return the round-robin quantum for the process identified by pid, in seconds.
5683
5684Value returned is a float.
5685[clinic start generated code]*/
5686
Larry Hastings2f936352014-08-05 14:04:04 +10005687static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005688os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5689/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005690{
5691 struct timespec interval;
5692 if (sched_rr_get_interval(pid, &interval)) {
5693 posix_error();
5694 return -1.0;
5695 }
Gregory P. Smithefcf08d2018-12-30 22:14:33 -08005696#ifdef _Py_MEMORY_SANITIZER
5697 __msan_unpoison(&interval, sizeof(interval));
5698#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005699 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5700}
5701#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005702
Larry Hastings2f936352014-08-05 14:04:04 +10005703
5704/*[clinic input]
5705os.sched_yield
5706
5707Voluntarily relinquish the CPU.
5708[clinic start generated code]*/
5709
Larry Hastings2f936352014-08-05 14:04:04 +10005710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005711os_sched_yield_impl(PyObject *module)
5712/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005713{
5714 if (sched_yield())
5715 return posix_error();
5716 Py_RETURN_NONE;
5717}
5718
Benjamin Peterson2740af82011-08-02 17:41:34 -05005719#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005720/* The minimum number of CPUs allocated in a cpu_set_t */
5721static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005722
Larry Hastings2f936352014-08-05 14:04:04 +10005723/*[clinic input]
5724os.sched_setaffinity
5725 pid: pid_t
5726 mask : object
5727 /
5728
5729Set the CPU affinity of the process identified by pid to mask.
5730
5731mask should be an iterable of integers identifying CPUs.
5732[clinic start generated code]*/
5733
Larry Hastings2f936352014-08-05 14:04:04 +10005734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005735os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5736/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005737{
Antoine Pitrou84869872012-08-04 16:16:35 +02005738 int ncpus;
5739 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005740 cpu_set_t *cpu_set = NULL;
5741 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005742
Larry Hastings2f936352014-08-05 14:04:04 +10005743 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005744 if (iterator == NULL)
5745 return NULL;
5746
5747 ncpus = NCPUS_START;
5748 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005749 cpu_set = CPU_ALLOC(ncpus);
5750 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005751 PyErr_NoMemory();
5752 goto error;
5753 }
Larry Hastings2f936352014-08-05 14:04:04 +10005754 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005755
5756 while ((item = PyIter_Next(iterator))) {
5757 long cpu;
5758 if (!PyLong_Check(item)) {
5759 PyErr_Format(PyExc_TypeError,
5760 "expected an iterator of ints, "
5761 "but iterator yielded %R",
5762 Py_TYPE(item));
5763 Py_DECREF(item);
5764 goto error;
5765 }
5766 cpu = PyLong_AsLong(item);
5767 Py_DECREF(item);
5768 if (cpu < 0) {
5769 if (!PyErr_Occurred())
5770 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5771 goto error;
5772 }
5773 if (cpu > INT_MAX - 1) {
5774 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5775 goto error;
5776 }
5777 if (cpu >= ncpus) {
5778 /* Grow CPU mask to fit the CPU number */
5779 int newncpus = ncpus;
5780 cpu_set_t *newmask;
5781 size_t newsetsize;
5782 while (newncpus <= cpu) {
5783 if (newncpus > INT_MAX / 2)
5784 newncpus = cpu + 1;
5785 else
5786 newncpus = newncpus * 2;
5787 }
5788 newmask = CPU_ALLOC(newncpus);
5789 if (newmask == NULL) {
5790 PyErr_NoMemory();
5791 goto error;
5792 }
5793 newsetsize = CPU_ALLOC_SIZE(newncpus);
5794 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005795 memcpy(newmask, cpu_set, setsize);
5796 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005797 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005798 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 ncpus = newncpus;
5800 }
Larry Hastings2f936352014-08-05 14:04:04 +10005801 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005802 }
5803 Py_CLEAR(iterator);
5804
Larry Hastings2f936352014-08-05 14:04:04 +10005805 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005806 posix_error();
5807 goto error;
5808 }
Larry Hastings2f936352014-08-05 14:04:04 +10005809 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005810 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005811
5812error:
Larry Hastings2f936352014-08-05 14:04:04 +10005813 if (cpu_set)
5814 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005815 Py_XDECREF(iterator);
5816 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005817}
5818
Larry Hastings2f936352014-08-05 14:04:04 +10005819
5820/*[clinic input]
5821os.sched_getaffinity
5822 pid: pid_t
5823 /
5824
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005825Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005826
5827The affinity is returned as a set of CPU identifiers.
5828[clinic start generated code]*/
5829
Larry Hastings2f936352014-08-05 14:04:04 +10005830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005831os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005832/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005833{
Antoine Pitrou84869872012-08-04 16:16:35 +02005834 int cpu, ncpus, count;
5835 size_t setsize;
5836 cpu_set_t *mask = NULL;
5837 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005838
Antoine Pitrou84869872012-08-04 16:16:35 +02005839 ncpus = NCPUS_START;
5840 while (1) {
5841 setsize = CPU_ALLOC_SIZE(ncpus);
5842 mask = CPU_ALLOC(ncpus);
5843 if (mask == NULL)
5844 return PyErr_NoMemory();
5845 if (sched_getaffinity(pid, setsize, mask) == 0)
5846 break;
5847 CPU_FREE(mask);
5848 if (errno != EINVAL)
5849 return posix_error();
5850 if (ncpus > INT_MAX / 2) {
5851 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5852 "a large enough CPU set");
5853 return NULL;
5854 }
5855 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005856 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005857
5858 res = PySet_New(NULL);
5859 if (res == NULL)
5860 goto error;
5861 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5862 if (CPU_ISSET_S(cpu, setsize, mask)) {
5863 PyObject *cpu_num = PyLong_FromLong(cpu);
5864 --count;
5865 if (cpu_num == NULL)
5866 goto error;
5867 if (PySet_Add(res, cpu_num)) {
5868 Py_DECREF(cpu_num);
5869 goto error;
5870 }
5871 Py_DECREF(cpu_num);
5872 }
5873 }
5874 CPU_FREE(mask);
5875 return res;
5876
5877error:
5878 if (mask)
5879 CPU_FREE(mask);
5880 Py_XDECREF(res);
5881 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005882}
5883
Benjamin Peterson2740af82011-08-02 17:41:34 -05005884#endif /* HAVE_SCHED_SETAFFINITY */
5885
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005886#endif /* HAVE_SCHED_H */
5887
Larry Hastings2f936352014-08-05 14:04:04 +10005888
Neal Norwitzb59798b2003-03-21 01:43:31 +00005889/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005890/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5891#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005892#define DEV_PTY_FILE "/dev/ptc"
5893#define HAVE_DEV_PTMX
5894#else
5895#define DEV_PTY_FILE "/dev/ptmx"
5896#endif
5897
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005898#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005899#ifdef HAVE_PTY_H
5900#include <pty.h>
5901#else
5902#ifdef HAVE_LIBUTIL_H
5903#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005904#else
5905#ifdef HAVE_UTIL_H
5906#include <util.h>
5907#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005908#endif /* HAVE_LIBUTIL_H */
5909#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005910#ifdef HAVE_STROPTS_H
5911#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005912#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005913#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005914
Larry Hastings2f936352014-08-05 14:04:04 +10005915
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005916#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005917/*[clinic input]
5918os.openpty
5919
5920Open a pseudo-terminal.
5921
5922Return a tuple of (master_fd, slave_fd) containing open file descriptors
5923for both the master and slave ends.
5924[clinic start generated code]*/
5925
Larry Hastings2f936352014-08-05 14:04:04 +10005926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005927os_openpty_impl(PyObject *module)
5928/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005929{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005930 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005931#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005934#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 PyOS_sighandler_t sig_saved;
Miss Islington (bot)d8234432018-12-30 18:39:00 -08005936#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005938#endif
5939#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005940
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005943 goto posix_error;
5944
5945 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5946 goto error;
5947 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5948 goto error;
5949
Neal Norwitzb59798b2003-03-21 01:43:31 +00005950#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5952 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953 goto posix_error;
5954 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5955 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005956
Victor Stinnerdaf45552013-08-28 00:53:59 +02005957 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005959 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005960
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005961#else
Victor Stinner000de532013-11-25 23:19:58 +01005962 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964 goto posix_error;
5965
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005967
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 /* change permission of slave */
5969 if (grantpt(master_fd) < 0) {
5970 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005971 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005973
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 /* unlock slave */
5975 if (unlockpt(master_fd) < 0) {
5976 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005977 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005979
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005981
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 slave_name = ptsname(master_fd); /* get name of slave */
5983 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005984 goto posix_error;
5985
5986 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005987 if (slave_fd == -1)
5988 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005989
5990 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5991 goto posix_error;
5992
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005993#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5995 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005996#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005998#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005999#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006000#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006001
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006003
Victor Stinnerdaf45552013-08-28 00:53:59 +02006004posix_error:
6005 posix_error();
6006error:
6007 if (master_fd != -1)
6008 close(master_fd);
6009 if (slave_fd != -1)
6010 close(slave_fd);
6011 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006012}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006013#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014
Larry Hastings2f936352014-08-05 14:04:04 +10006015
Fred Drake8cef4cf2000-06-28 16:40:38 +00006016#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006017/*[clinic input]
6018os.forkpty
6019
6020Fork a new process with a new pseudo-terminal as controlling tty.
6021
6022Returns a tuple of (pid, master_fd).
6023Like fork(), return pid of 0 to the child process,
6024and pid of child to the parent process.
6025To both, return fd of newly opened pseudo-terminal.
6026[clinic start generated code]*/
6027
Larry Hastings2f936352014-08-05 14:04:04 +10006028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006029os_forkpty_impl(PyObject *module)
6030/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006031{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006032 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006034
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006035 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 pid = forkpty(&master_fd, NULL, NULL, NULL);
6037 if (pid == 0) {
6038 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006039 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006040 } else {
6041 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006042 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 }
6044 if (pid == -1)
6045 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006047}
Larry Hastings2f936352014-08-05 14:04:04 +10006048#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006049
Ross Lagerwall7807c352011-03-17 20:20:30 +02006050
Guido van Rossumad0ee831995-03-01 10:34:45 +00006051#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006052/*[clinic input]
6053os.getegid
6054
6055Return the current process's effective group id.
6056[clinic start generated code]*/
6057
Larry Hastings2f936352014-08-05 14:04:04 +10006058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006059os_getegid_impl(PyObject *module)
6060/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006061{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006062 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006063}
Larry Hastings2f936352014-08-05 14:04:04 +10006064#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006066
Guido van Rossumad0ee831995-03-01 10:34:45 +00006067#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006068/*[clinic input]
6069os.geteuid
6070
6071Return the current process's effective user id.
6072[clinic start generated code]*/
6073
Larry Hastings2f936352014-08-05 14:04:04 +10006074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006075os_geteuid_impl(PyObject *module)
6076/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006077{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006078 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006079}
Larry Hastings2f936352014-08-05 14:04:04 +10006080#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Guido van Rossumad0ee831995-03-01 10:34:45 +00006083#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006084/*[clinic input]
6085os.getgid
6086
6087Return the current process's group id.
6088[clinic start generated code]*/
6089
Larry Hastings2f936352014-08-05 14:04:04 +10006090static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006091os_getgid_impl(PyObject *module)
6092/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006093{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006094 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006095}
Larry Hastings2f936352014-08-05 14:04:04 +10006096#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006098
Berker Peksag39404992016-09-15 20:45:16 +03006099#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006100/*[clinic input]
6101os.getpid
6102
6103Return the current process id.
6104[clinic start generated code]*/
6105
Larry Hastings2f936352014-08-05 14:04:04 +10006106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006107os_getpid_impl(PyObject *module)
6108/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006109{
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006111}
Berker Peksag39404992016-09-15 20:45:16 +03006112#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006113
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006114#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006115
6116/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006117PyDoc_STRVAR(posix_getgrouplist__doc__,
6118"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6119Returns a list of groups to which a user belongs.\n\n\
6120 user: username to lookup\n\
6121 group: base group id of the user");
6122
6123static PyObject *
6124posix_getgrouplist(PyObject *self, PyObject *args)
6125{
6126#ifdef NGROUPS_MAX
6127#define MAX_GROUPS NGROUPS_MAX
6128#else
6129 /* defined to be 16 on Solaris7, so this should be a small number */
6130#define MAX_GROUPS 64
6131#endif
6132
6133 const char *user;
6134 int i, ngroups;
6135 PyObject *list;
6136#ifdef __APPLE__
6137 int *groups, basegid;
6138#else
6139 gid_t *groups, basegid;
6140#endif
6141 ngroups = MAX_GROUPS;
6142
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006143#ifdef __APPLE__
6144 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006145 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006146#else
6147 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6148 _Py_Gid_Converter, &basegid))
6149 return NULL;
6150#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006151
6152#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006153 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006154#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006155 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006156#endif
6157 if (groups == NULL)
6158 return PyErr_NoMemory();
6159
6160 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6161 PyMem_Del(groups);
6162 return posix_error();
6163 }
6164
Gregory P. Smithefcf08d2018-12-30 22:14:33 -08006165#ifdef _Py_MEMORY_SANITIZER
6166 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6167 __msan_unpoison(&ngroups, sizeof(ngroups));
6168 __msan_unpoison(groups, ngroups*sizeof(*groups));
6169#endif
6170
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006171 list = PyList_New(ngroups);
6172 if (list == NULL) {
6173 PyMem_Del(groups);
6174 return NULL;
6175 }
6176
6177 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006178#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006179 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006180#else
6181 PyObject *o = _PyLong_FromGid(groups[i]);
6182#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006183 if (o == NULL) {
6184 Py_DECREF(list);
6185 PyMem_Del(groups);
6186 return NULL;
6187 }
6188 PyList_SET_ITEM(list, i, o);
6189 }
6190
6191 PyMem_Del(groups);
6192
6193 return list;
6194}
Larry Hastings2f936352014-08-05 14:04:04 +10006195#endif /* HAVE_GETGROUPLIST */
6196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006197
Fred Drakec9680921999-12-13 16:37:25 +00006198#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006199/*[clinic input]
6200os.getgroups
6201
6202Return list of supplemental group IDs for the process.
6203[clinic start generated code]*/
6204
Larry Hastings2f936352014-08-05 14:04:04 +10006205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006206os_getgroups_impl(PyObject *module)
6207/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006208{
6209 PyObject *result = NULL;
6210
Fred Drakec9680921999-12-13 16:37:25 +00006211#ifdef NGROUPS_MAX
6212#define MAX_GROUPS NGROUPS_MAX
6213#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006214 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006215#define MAX_GROUPS 64
6216#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006217 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006218
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006219 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006220 * This is a helper variable to store the intermediate result when
6221 * that happens.
6222 *
6223 * To keep the code readable the OSX behaviour is unconditional,
6224 * according to the POSIX spec this should be safe on all unix-y
6225 * systems.
6226 */
6227 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006229
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006230#ifdef __APPLE__
6231 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6232 * there are more groups than can fit in grouplist. Therefore, on OS X
6233 * always first call getgroups with length 0 to get the actual number
6234 * of groups.
6235 */
6236 n = getgroups(0, NULL);
6237 if (n < 0) {
6238 return posix_error();
6239 } else if (n <= MAX_GROUPS) {
6240 /* groups will fit in existing array */
6241 alt_grouplist = grouplist;
6242 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006243 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006244 if (alt_grouplist == NULL) {
Zackery Spytz602d3072018-12-07 05:17:43 -07006245 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006246 }
6247 }
6248
6249 n = getgroups(n, alt_grouplist);
6250 if (n == -1) {
6251 if (alt_grouplist != grouplist) {
6252 PyMem_Free(alt_grouplist);
6253 }
6254 return posix_error();
6255 }
6256#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006258 if (n < 0) {
6259 if (errno == EINVAL) {
6260 n = getgroups(0, NULL);
6261 if (n == -1) {
6262 return posix_error();
6263 }
6264 if (n == 0) {
6265 /* Avoid malloc(0) */
6266 alt_grouplist = grouplist;
6267 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006268 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006269 if (alt_grouplist == NULL) {
Zackery Spytz602d3072018-12-07 05:17:43 -07006270 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006271 }
6272 n = getgroups(n, alt_grouplist);
6273 if (n == -1) {
6274 PyMem_Free(alt_grouplist);
6275 return posix_error();
6276 }
6277 }
6278 } else {
6279 return posix_error();
6280 }
6281 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006282#endif
6283
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006284 result = PyList_New(n);
6285 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 int i;
6287 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006288 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006289 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006290 Py_DECREF(result);
6291 result = NULL;
6292 break;
Fred Drakec9680921999-12-13 16:37:25 +00006293 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006295 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006296 }
6297
6298 if (alt_grouplist != grouplist) {
6299 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006301
Fred Drakec9680921999-12-13 16:37:25 +00006302 return result;
6303}
Larry Hastings2f936352014-08-05 14:04:04 +10006304#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006305
Antoine Pitroub7572f02009-12-02 20:46:48 +00006306#ifdef HAVE_INITGROUPS
6307PyDoc_STRVAR(posix_initgroups__doc__,
6308"initgroups(username, gid) -> None\n\n\
6309Call the system initgroups() to initialize the group access list with all of\n\
6310the groups of which the specified username is a member, plus the specified\n\
6311group id.");
6312
Larry Hastings2f936352014-08-05 14:04:04 +10006313/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006314static PyObject *
6315posix_initgroups(PyObject *self, PyObject *args)
6316{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006317 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006318 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006319 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006320#ifdef __APPLE__
6321 int gid;
6322#else
6323 gid_t gid;
6324#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006325
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006326#ifdef __APPLE__
6327 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6328 PyUnicode_FSConverter, &oname,
6329 &gid))
6330#else
6331 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6332 PyUnicode_FSConverter, &oname,
6333 _Py_Gid_Converter, &gid))
6334#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006336 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006337
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006338 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006339 Py_DECREF(oname);
6340 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006342
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006343 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006344}
Larry Hastings2f936352014-08-05 14:04:04 +10006345#endif /* HAVE_INITGROUPS */
6346
Antoine Pitroub7572f02009-12-02 20:46:48 +00006347
Martin v. Löwis606edc12002-06-13 21:09:11 +00006348#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006349/*[clinic input]
6350os.getpgid
6351
6352 pid: pid_t
6353
6354Call the system call getpgid(), and return the result.
6355[clinic start generated code]*/
6356
Larry Hastings2f936352014-08-05 14:04:04 +10006357static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006358os_getpgid_impl(PyObject *module, pid_t pid)
6359/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006360{
6361 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 if (pgid < 0)
6363 return posix_error();
6364 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006365}
6366#endif /* HAVE_GETPGID */
6367
6368
Guido van Rossumb6775db1994-08-01 11:34:53 +00006369#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006370/*[clinic input]
6371os.getpgrp
6372
6373Return the current process group id.
6374[clinic start generated code]*/
6375
Larry Hastings2f936352014-08-05 14:04:04 +10006376static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006377os_getpgrp_impl(PyObject *module)
6378/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006379{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006380#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006382#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006384#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006385}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006386#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006387
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006388
Guido van Rossumb6775db1994-08-01 11:34:53 +00006389#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006390/*[clinic input]
6391os.setpgrp
6392
6393Make the current process the leader of its process group.
6394[clinic start generated code]*/
6395
Larry Hastings2f936352014-08-05 14:04:04 +10006396static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006397os_setpgrp_impl(PyObject *module)
6398/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006399{
Guido van Rossum64933891994-10-20 21:56:42 +00006400#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006402#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006404#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006406 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006407}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006408#endif /* HAVE_SETPGRP */
6409
Guido van Rossumad0ee831995-03-01 10:34:45 +00006410#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006411
6412#ifdef MS_WINDOWS
6413#include <tlhelp32.h>
6414
6415static PyObject*
6416win32_getppid()
6417{
6418 HANDLE snapshot;
6419 pid_t mypid;
6420 PyObject* result = NULL;
6421 BOOL have_record;
6422 PROCESSENTRY32 pe;
6423
6424 mypid = getpid(); /* This function never fails */
6425
6426 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6427 if (snapshot == INVALID_HANDLE_VALUE)
6428 return PyErr_SetFromWindowsErr(GetLastError());
6429
6430 pe.dwSize = sizeof(pe);
6431 have_record = Process32First(snapshot, &pe);
6432 while (have_record) {
6433 if (mypid == (pid_t)pe.th32ProcessID) {
6434 /* We could cache the ulong value in a static variable. */
6435 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6436 break;
6437 }
6438
6439 have_record = Process32Next(snapshot, &pe);
6440 }
6441
6442 /* If our loop exits and our pid was not found (result will be NULL)
6443 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6444 * error anyway, so let's raise it. */
6445 if (!result)
6446 result = PyErr_SetFromWindowsErr(GetLastError());
6447
6448 CloseHandle(snapshot);
6449
6450 return result;
6451}
6452#endif /*MS_WINDOWS*/
6453
Larry Hastings2f936352014-08-05 14:04:04 +10006454
6455/*[clinic input]
6456os.getppid
6457
6458Return the parent's process id.
6459
6460If the parent process has already exited, Windows machines will still
6461return its id; others systems will return the id of the 'init' process (1).
6462[clinic start generated code]*/
6463
Larry Hastings2f936352014-08-05 14:04:04 +10006464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006465os_getppid_impl(PyObject *module)
6466/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006467{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006468#ifdef MS_WINDOWS
6469 return win32_getppid();
6470#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006471 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006472#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006473}
6474#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006476
Fred Drake12c6e2d1999-12-14 21:25:03 +00006477#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006478/*[clinic input]
6479os.getlogin
6480
6481Return the actual login name.
6482[clinic start generated code]*/
6483
Larry Hastings2f936352014-08-05 14:04:04 +10006484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006485os_getlogin_impl(PyObject *module)
6486/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006487{
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006489#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006490 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006491 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006492
6493 if (GetUserNameW(user_name, &num_chars)) {
6494 /* num_chars is the number of unicode chars plus null terminator */
6495 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006496 }
6497 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006498 result = PyErr_SetFromWindowsErr(GetLastError());
6499#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 char *name;
6501 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006502
Victor Stinner8c62be82010-05-06 00:08:46 +00006503 errno = 0;
6504 name = getlogin();
6505 if (name == NULL) {
6506 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006507 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006508 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006509 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006510 }
6511 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006512 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006514#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006515 return result;
6516}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006517#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006518
Larry Hastings2f936352014-08-05 14:04:04 +10006519
Guido van Rossumad0ee831995-03-01 10:34:45 +00006520#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006521/*[clinic input]
6522os.getuid
6523
6524Return the current process's user id.
6525[clinic start generated code]*/
6526
Larry Hastings2f936352014-08-05 14:04:04 +10006527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006528os_getuid_impl(PyObject *module)
6529/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006530{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006531 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006532}
Larry Hastings2f936352014-08-05 14:04:04 +10006533#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006535
Brian Curtineb24d742010-04-12 17:16:38 +00006536#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006537#define HAVE_KILL
6538#endif /* MS_WINDOWS */
6539
6540#ifdef HAVE_KILL
6541/*[clinic input]
6542os.kill
6543
6544 pid: pid_t
6545 signal: Py_ssize_t
6546 /
6547
6548Kill a process with a signal.
6549[clinic start generated code]*/
6550
Larry Hastings2f936352014-08-05 14:04:04 +10006551static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006552os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6553/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006554#ifndef MS_WINDOWS
6555{
6556 if (kill(pid, (int)signal) == -1)
6557 return posix_error();
6558 Py_RETURN_NONE;
6559}
6560#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006561{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006562 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006563 DWORD sig = (DWORD)signal;
6564 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006566
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 /* Console processes which share a common console can be sent CTRL+C or
6568 CTRL+BREAK events, provided they handle said events. */
6569 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006570 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 err = GetLastError();
6572 PyErr_SetFromWindowsErr(err);
6573 }
6574 else
6575 Py_RETURN_NONE;
6576 }
Brian Curtineb24d742010-04-12 17:16:38 +00006577
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6579 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006580 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 if (handle == NULL) {
6582 err = GetLastError();
6583 return PyErr_SetFromWindowsErr(err);
6584 }
Brian Curtineb24d742010-04-12 17:16:38 +00006585
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 if (TerminateProcess(handle, sig) == 0) {
6587 err = GetLastError();
6588 result = PyErr_SetFromWindowsErr(err);
6589 } else {
6590 Py_INCREF(Py_None);
6591 result = Py_None;
6592 }
Brian Curtineb24d742010-04-12 17:16:38 +00006593
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 CloseHandle(handle);
6595 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006596}
Larry Hastings2f936352014-08-05 14:04:04 +10006597#endif /* !MS_WINDOWS */
6598#endif /* HAVE_KILL */
6599
6600
6601#ifdef HAVE_KILLPG
6602/*[clinic input]
6603os.killpg
6604
6605 pgid: pid_t
6606 signal: int
6607 /
6608
6609Kill a process group with a signal.
6610[clinic start generated code]*/
6611
Larry Hastings2f936352014-08-05 14:04:04 +10006612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006613os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6614/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006615{
6616 /* XXX some man pages make the `pgid` parameter an int, others
6617 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6618 take the same type. Moreover, pid_t is always at least as wide as
6619 int (else compilation of this module fails), which is safe. */
6620 if (killpg(pgid, signal) == -1)
6621 return posix_error();
6622 Py_RETURN_NONE;
6623}
6624#endif /* HAVE_KILLPG */
6625
Brian Curtineb24d742010-04-12 17:16:38 +00006626
Guido van Rossumc0125471996-06-28 18:55:32 +00006627#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006628#ifdef HAVE_SYS_LOCK_H
6629#include <sys/lock.h>
6630#endif
6631
Larry Hastings2f936352014-08-05 14:04:04 +10006632/*[clinic input]
6633os.plock
6634 op: int
6635 /
6636
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006637Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006638[clinic start generated code]*/
6639
Larry Hastings2f936352014-08-05 14:04:04 +10006640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006641os_plock_impl(PyObject *module, int op)
6642/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006643{
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 if (plock(op) == -1)
6645 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006646 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006647}
Larry Hastings2f936352014-08-05 14:04:04 +10006648#endif /* HAVE_PLOCK */
6649
Guido van Rossumc0125471996-06-28 18:55:32 +00006650
Guido van Rossumb6775db1994-08-01 11:34:53 +00006651#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006652/*[clinic input]
6653os.setuid
6654
6655 uid: uid_t
6656 /
6657
6658Set the current process's user id.
6659[clinic start generated code]*/
6660
Larry Hastings2f936352014-08-05 14:04:04 +10006661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006662os_setuid_impl(PyObject *module, uid_t uid)
6663/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006664{
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 if (setuid(uid) < 0)
6666 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006667 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006668}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006669#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006671
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006672#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006673/*[clinic input]
6674os.seteuid
6675
6676 euid: uid_t
6677 /
6678
6679Set the current process's effective user id.
6680[clinic start generated code]*/
6681
Larry Hastings2f936352014-08-05 14:04:04 +10006682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006683os_seteuid_impl(PyObject *module, uid_t euid)
6684/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006685{
6686 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006688 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006689}
6690#endif /* HAVE_SETEUID */
6691
Larry Hastings2f936352014-08-05 14:04:04 +10006692
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006693#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006694/*[clinic input]
6695os.setegid
6696
6697 egid: gid_t
6698 /
6699
6700Set the current process's effective group id.
6701[clinic start generated code]*/
6702
Larry Hastings2f936352014-08-05 14:04:04 +10006703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006704os_setegid_impl(PyObject *module, gid_t egid)
6705/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006706{
6707 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006708 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006709 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006710}
6711#endif /* HAVE_SETEGID */
6712
Larry Hastings2f936352014-08-05 14:04:04 +10006713
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006714#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006715/*[clinic input]
6716os.setreuid
6717
6718 ruid: uid_t
6719 euid: uid_t
6720 /
6721
6722Set the current process's real and effective user ids.
6723[clinic start generated code]*/
6724
Larry Hastings2f936352014-08-05 14:04:04 +10006725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006726os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6727/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006728{
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 if (setreuid(ruid, euid) < 0) {
6730 return posix_error();
6731 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006732 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006734}
6735#endif /* HAVE_SETREUID */
6736
Larry Hastings2f936352014-08-05 14:04:04 +10006737
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006738#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006739/*[clinic input]
6740os.setregid
6741
6742 rgid: gid_t
6743 egid: gid_t
6744 /
6745
6746Set the current process's real and effective group ids.
6747[clinic start generated code]*/
6748
Larry Hastings2f936352014-08-05 14:04:04 +10006749static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006750os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6751/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006752{
6753 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006755 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006756}
6757#endif /* HAVE_SETREGID */
6758
Larry Hastings2f936352014-08-05 14:04:04 +10006759
Guido van Rossumb6775db1994-08-01 11:34:53 +00006760#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006761/*[clinic input]
6762os.setgid
6763 gid: gid_t
6764 /
6765
6766Set the current process's group id.
6767[clinic start generated code]*/
6768
Larry Hastings2f936352014-08-05 14:04:04 +10006769static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006770os_setgid_impl(PyObject *module, gid_t gid)
6771/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006772{
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 if (setgid(gid) < 0)
6774 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006775 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006776}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006777#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006778
Larry Hastings2f936352014-08-05 14:04:04 +10006779
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006780#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006781/*[clinic input]
6782os.setgroups
6783
6784 groups: object
6785 /
6786
6787Set the groups of the current process to list.
6788[clinic start generated code]*/
6789
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006790static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006791os_setgroups(PyObject *module, PyObject *groups)
6792/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006793{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006794 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006796
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 if (!PySequence_Check(groups)) {
6798 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6799 return NULL;
6800 }
6801 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006802 if (len < 0) {
6803 return NULL;
6804 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 if (len > MAX_GROUPS) {
6806 PyErr_SetString(PyExc_ValueError, "too many groups");
6807 return NULL;
6808 }
6809 for(i = 0; i < len; i++) {
6810 PyObject *elem;
6811 elem = PySequence_GetItem(groups, i);
6812 if (!elem)
6813 return NULL;
6814 if (!PyLong_Check(elem)) {
6815 PyErr_SetString(PyExc_TypeError,
6816 "groups must be integers");
6817 Py_DECREF(elem);
6818 return NULL;
6819 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006820 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 Py_DECREF(elem);
6822 return NULL;
6823 }
6824 }
6825 Py_DECREF(elem);
6826 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006827
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 if (setgroups(len, grouplist) < 0)
6829 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006830 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006831}
6832#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006833
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006834#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6835static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006836wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006837{
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 PyObject *result;
6839 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006840 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006841
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 if (pid == -1)
6843 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006844
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 if (struct_rusage == NULL) {
6846 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6847 if (m == NULL)
6848 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006849 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 Py_DECREF(m);
6851 if (struct_rusage == NULL)
6852 return NULL;
6853 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006854
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6856 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6857 if (!result)
6858 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006859
6860#ifndef doubletime
6861#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6862#endif
6863
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006865 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006867 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6870 SET_INT(result, 2, ru->ru_maxrss);
6871 SET_INT(result, 3, ru->ru_ixrss);
6872 SET_INT(result, 4, ru->ru_idrss);
6873 SET_INT(result, 5, ru->ru_isrss);
6874 SET_INT(result, 6, ru->ru_minflt);
6875 SET_INT(result, 7, ru->ru_majflt);
6876 SET_INT(result, 8, ru->ru_nswap);
6877 SET_INT(result, 9, ru->ru_inblock);
6878 SET_INT(result, 10, ru->ru_oublock);
6879 SET_INT(result, 11, ru->ru_msgsnd);
6880 SET_INT(result, 12, ru->ru_msgrcv);
6881 SET_INT(result, 13, ru->ru_nsignals);
6882 SET_INT(result, 14, ru->ru_nvcsw);
6883 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006884#undef SET_INT
6885
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 if (PyErr_Occurred()) {
6887 Py_DECREF(result);
6888 return NULL;
6889 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006890
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892}
6893#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6894
Larry Hastings2f936352014-08-05 14:04:04 +10006895
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006897/*[clinic input]
6898os.wait3
6899
6900 options: int
6901Wait for completion of a child process.
6902
6903Returns a tuple of information about the child process:
6904 (pid, status, rusage)
6905[clinic start generated code]*/
6906
Larry Hastings2f936352014-08-05 14:04:04 +10006907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006908os_wait3_impl(PyObject *module, int options)
6909/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006910{
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006913 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 WAIT_TYPE status;
6915 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006916
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006917 do {
6918 Py_BEGIN_ALLOW_THREADS
6919 pid = wait3(&status, options, &ru);
6920 Py_END_ALLOW_THREADS
6921 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6922 if (pid < 0)
6923 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924
Victor Stinner4195b5c2012-02-08 23:03:19 +01006925 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006926}
6927#endif /* HAVE_WAIT3 */
6928
Larry Hastings2f936352014-08-05 14:04:04 +10006929
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006930#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006931/*[clinic input]
6932
6933os.wait4
6934
6935 pid: pid_t
6936 options: int
6937
6938Wait for completion of a specific child process.
6939
6940Returns a tuple of information about the child process:
6941 (pid, status, rusage)
6942[clinic start generated code]*/
6943
Larry Hastings2f936352014-08-05 14:04:04 +10006944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006945os_wait4_impl(PyObject *module, pid_t pid, int options)
6946/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006947{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006948 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006950 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 WAIT_TYPE status;
6952 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006953
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006954 do {
6955 Py_BEGIN_ALLOW_THREADS
6956 res = wait4(pid, &status, options, &ru);
6957 Py_END_ALLOW_THREADS
6958 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6959 if (res < 0)
6960 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006961
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006962 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006963}
6964#endif /* HAVE_WAIT4 */
6965
Larry Hastings2f936352014-08-05 14:04:04 +10006966
Ross Lagerwall7807c352011-03-17 20:20:30 +02006967#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006968/*[clinic input]
6969os.waitid
6970
6971 idtype: idtype_t
6972 Must be one of be P_PID, P_PGID or P_ALL.
6973 id: id_t
6974 The id to wait on.
6975 options: int
6976 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6977 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6978 /
6979
6980Returns the result of waiting for a process or processes.
6981
6982Returns either waitid_result or None if WNOHANG is specified and there are
6983no children in a waitable state.
6984[clinic start generated code]*/
6985
Larry Hastings2f936352014-08-05 14:04:04 +10006986static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006987os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6988/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006989{
6990 PyObject *result;
6991 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006992 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006993 siginfo_t si;
6994 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006995
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006996 do {
6997 Py_BEGIN_ALLOW_THREADS
6998 res = waitid(idtype, id, &si, options);
6999 Py_END_ALLOW_THREADS
7000 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7001 if (res < 0)
7002 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007003
7004 if (si.si_pid == 0)
7005 Py_RETURN_NONE;
7006
7007 result = PyStructSequence_New(&WaitidResultType);
7008 if (!result)
7009 return NULL;
7010
7011 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007012 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007013 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7014 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7015 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7016 if (PyErr_Occurred()) {
7017 Py_DECREF(result);
7018 return NULL;
7019 }
7020
7021 return result;
7022}
Larry Hastings2f936352014-08-05 14:04:04 +10007023#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007024
Larry Hastings2f936352014-08-05 14:04:04 +10007025
7026#if defined(HAVE_WAITPID)
7027/*[clinic input]
7028os.waitpid
7029 pid: pid_t
7030 options: int
7031 /
7032
7033Wait for completion of a given child process.
7034
7035Returns a tuple of information regarding the child process:
7036 (pid, status)
7037
7038The options argument is ignored on Windows.
7039[clinic start generated code]*/
7040
Larry Hastings2f936352014-08-05 14:04:04 +10007041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007042os_waitpid_impl(PyObject *module, pid_t pid, int options)
7043/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007044{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007045 pid_t res;
7046 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 WAIT_TYPE status;
7048 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007049
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007050 do {
7051 Py_BEGIN_ALLOW_THREADS
7052 res = waitpid(pid, &status, options);
7053 Py_END_ALLOW_THREADS
7054 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7055 if (res < 0)
7056 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007057
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007058 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007059}
Tim Petersab034fa2002-02-01 11:27:43 +00007060#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007061/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007062/*[clinic input]
7063os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007064 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007065 options: int
7066 /
7067
7068Wait for completion of a given process.
7069
7070Returns a tuple of information regarding the process:
7071 (pid, status << 8)
7072
7073The options argument is ignored on Windows.
7074[clinic start generated code]*/
7075
Larry Hastings2f936352014-08-05 14:04:04 +10007076static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007077os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007078/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007079{
7080 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007081 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007082 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007083
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007084 do {
7085 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007086 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007087 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007088 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007089 Py_END_ALLOW_THREADS
7090 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007091 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007092 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007093
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007095 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007096}
Larry Hastings2f936352014-08-05 14:04:04 +10007097#endif
7098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007099
Guido van Rossumad0ee831995-03-01 10:34:45 +00007100#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007101/*[clinic input]
7102os.wait
7103
7104Wait for completion of a child process.
7105
7106Returns a tuple of information about the child process:
7107 (pid, status)
7108[clinic start generated code]*/
7109
Larry Hastings2f936352014-08-05 14:04:04 +10007110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007111os_wait_impl(PyObject *module)
7112/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007113{
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007115 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007116 WAIT_TYPE status;
7117 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007118
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007119 do {
7120 Py_BEGIN_ALLOW_THREADS
7121 pid = wait(&status);
7122 Py_END_ALLOW_THREADS
7123 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7124 if (pid < 0)
7125 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007126
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007128}
Larry Hastings2f936352014-08-05 14:04:04 +10007129#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007131
Larry Hastings9cf065c2012-06-22 16:30:09 -07007132#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7133PyDoc_STRVAR(readlink__doc__,
7134"readlink(path, *, dir_fd=None) -> path\n\n\
7135Return a string representing the path to which the symbolic link points.\n\
7136\n\
7137If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7138 and path should be relative; path will then be relative to that directory.\n\
7139dir_fd may not be implemented on your platform.\n\
7140 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007141#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007142
Guido van Rossumb6775db1994-08-01 11:34:53 +00007143#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007144
Larry Hastings2f936352014-08-05 14:04:04 +10007145/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007146static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007148{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007149 path_t path;
7150 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007151 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152 ssize_t length;
7153 PyObject *return_value = NULL;
7154 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007155
Larry Hastings9cf065c2012-06-22 16:30:09 -07007156 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007157 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007158 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7159 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007160 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007161 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007162
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164#ifdef HAVE_READLINKAT
7165 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007166 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007167 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007168#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007169 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170 Py_END_ALLOW_THREADS
7171
7172 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007173 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007174 goto exit;
7175 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007176 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007177
7178 if (PyUnicode_Check(path.object))
7179 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7180 else
7181 return_value = PyBytes_FromStringAndSize(buffer, length);
7182exit:
7183 path_cleanup(&path);
7184 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007185}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007186
Guido van Rossumb6775db1994-08-01 11:34:53 +00007187#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007188
Larry Hastings2f936352014-08-05 14:04:04 +10007189#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7190
7191static PyObject *
7192win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7193{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007194 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007195 DWORD n_bytes_returned;
7196 DWORD io_result;
7197 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007198 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007199 HANDLE reparse_point_handle;
7200
Martin Panter70214ad2016-08-04 02:38:59 +00007201 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7202 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007203 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007204
7205 static char *keywords[] = {"path", "dir_fd", NULL};
7206
7207 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7208 &po,
7209 dir_fd_unavailable, &dir_fd
7210 ))
7211 return NULL;
7212
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007213 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007214 if (path == NULL)
7215 return NULL;
7216
7217 /* First get a handle to the reparse point */
7218 Py_BEGIN_ALLOW_THREADS
7219 reparse_point_handle = CreateFileW(
7220 path,
7221 0,
7222 0,
7223 0,
7224 OPEN_EXISTING,
7225 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7226 0);
7227 Py_END_ALLOW_THREADS
7228
7229 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7230 return win32_error_object("readlink", po);
7231
7232 Py_BEGIN_ALLOW_THREADS
7233 /* New call DeviceIoControl to read the reparse point */
7234 io_result = DeviceIoControl(
7235 reparse_point_handle,
7236 FSCTL_GET_REPARSE_POINT,
7237 0, 0, /* in buffer */
7238 target_buffer, sizeof(target_buffer),
7239 &n_bytes_returned,
7240 0 /* we're not using OVERLAPPED_IO */
7241 );
7242 CloseHandle(reparse_point_handle);
7243 Py_END_ALLOW_THREADS
7244
7245 if (io_result==0)
7246 return win32_error_object("readlink", po);
7247
7248 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7249 {
7250 PyErr_SetString(PyExc_ValueError,
7251 "not a symbolic link");
7252 return NULL;
7253 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007254 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7255 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007256
7257 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007258 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007259 return result;
7260}
7261
7262#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7263
7264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007265
Larry Hastings9cf065c2012-06-22 16:30:09 -07007266#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007267
7268#if defined(MS_WINDOWS)
7269
7270/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007271static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007272
Larry Hastings9cf065c2012-06-22 16:30:09 -07007273static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007274check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275{
7276 HINSTANCE hKernel32;
7277 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007278 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007279 return 1;
7280 hKernel32 = GetModuleHandleW(L"KERNEL32");
7281 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7282 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007283 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007284}
7285
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007286/* Remove the last portion of the path - return 0 on success */
7287static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007288_dirnameW(WCHAR *path)
7289{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007290 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007291 size_t length = wcsnlen_s(path, MAX_PATH);
7292 if (length == MAX_PATH) {
7293 return -1;
7294 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295
7296 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007297 for(ptr = path + length; ptr != path; ptr--) {
7298 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007299 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007300 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007301 }
7302 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007303 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007304}
7305
Victor Stinner31b3b922013-06-05 01:49:17 +02007306/* Is this path absolute? */
7307static int
7308_is_absW(const WCHAR *path)
7309{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007310 return path[0] == L'\\' || path[0] == L'/' ||
7311 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007312}
7313
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007314/* join root and rest with a backslash - return 0 on success */
7315static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007316_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7317{
Victor Stinner31b3b922013-06-05 01:49:17 +02007318 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007319 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320 }
7321
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007322 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7323 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007324 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007325
7326 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7327 return -1;
7328 }
7329
7330 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007331}
7332
Victor Stinner31b3b922013-06-05 01:49:17 +02007333/* Return True if the path at src relative to dest is a directory */
7334static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007335_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007336{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007337 WIN32_FILE_ATTRIBUTE_DATA src_info;
7338 WCHAR dest_parent[MAX_PATH];
7339 WCHAR src_resolved[MAX_PATH] = L"";
7340
7341 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007342 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7343 _dirnameW(dest_parent)) {
7344 return 0;
7345 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007346 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007347 if (_joinW(src_resolved, dest_parent, src)) {
7348 return 0;
7349 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007350 return (
7351 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7352 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7353 );
7354}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007355#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007356
Larry Hastings2f936352014-08-05 14:04:04 +10007357
7358/*[clinic input]
7359os.symlink
7360 src: path_t
7361 dst: path_t
7362 target_is_directory: bool = False
7363 *
7364 dir_fd: dir_fd(requires='symlinkat')=None
7365
7366# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7367
7368Create a symbolic link pointing to src named dst.
7369
7370target_is_directory is required on Windows if the target is to be
7371 interpreted as a directory. (On Windows, symlink requires
7372 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7373 target_is_directory is ignored on non-Windows platforms.
7374
7375If dir_fd is not None, it should be a file descriptor open to a directory,
7376 and path should be relative; path will then be relative to that directory.
7377dir_fd may not be implemented on your platform.
7378 If it is unavailable, using it will raise a NotImplementedError.
7379
7380[clinic start generated code]*/
7381
Larry Hastings2f936352014-08-05 14:04:04 +10007382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007383os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007384 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007385/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007386{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007387#ifdef MS_WINDOWS
7388 DWORD result;
7389#else
7390 int result;
7391#endif
7392
Larry Hastings9cf065c2012-06-22 16:30:09 -07007393#ifdef MS_WINDOWS
7394 if (!check_CreateSymbolicLink()) {
7395 PyErr_SetString(PyExc_NotImplementedError,
7396 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007397 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007398 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399 if (!win32_can_symlink) {
7400 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007401 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007402 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403#endif
7404
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007406
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007408 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007409 /* if src is a directory, ensure target_is_directory==1 */
7410 target_is_directory |= _check_dirW(src->wide, dst->wide);
7411 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7412 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007413 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007414 Py_END_ALLOW_THREADS
7415
Larry Hastings2f936352014-08-05 14:04:04 +10007416 if (!result)
7417 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007418
7419#else
7420
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007421 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7422 PyErr_SetString(PyExc_ValueError,
7423 "symlink: src and dst must be the same type");
7424 return NULL;
7425 }
7426
Larry Hastings9cf065c2012-06-22 16:30:09 -07007427 Py_BEGIN_ALLOW_THREADS
7428#if HAVE_SYMLINKAT
7429 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007430 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007431 else
7432#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007433 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434 Py_END_ALLOW_THREADS
7435
Larry Hastings2f936352014-08-05 14:04:04 +10007436 if (result)
7437 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438#endif
7439
Larry Hastings2f936352014-08-05 14:04:04 +10007440 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007441}
7442#endif /* HAVE_SYMLINK */
7443
Larry Hastings9cf065c2012-06-22 16:30:09 -07007444
Brian Curtind40e6f72010-07-08 21:39:08 +00007445
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007446
Larry Hastings605a62d2012-06-24 04:33:36 -07007447static PyStructSequence_Field times_result_fields[] = {
7448 {"user", "user time"},
7449 {"system", "system time"},
7450 {"children_user", "user time of children"},
7451 {"children_system", "system time of children"},
7452 {"elapsed", "elapsed time since an arbitrary point in the past"},
7453 {NULL}
7454};
7455
7456PyDoc_STRVAR(times_result__doc__,
7457"times_result: Result from os.times().\n\n\
7458This object may be accessed either as a tuple of\n\
7459 (user, system, children_user, children_system, elapsed),\n\
7460or via the attributes user, system, children_user, children_system,\n\
7461and elapsed.\n\
7462\n\
7463See os.times for more information.");
7464
7465static PyStructSequence_Desc times_result_desc = {
7466 "times_result", /* name */
7467 times_result__doc__, /* doc */
7468 times_result_fields,
7469 5
7470};
7471
7472static PyTypeObject TimesResultType;
7473
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007474#ifdef MS_WINDOWS
7475#define HAVE_TIMES /* mandatory, for the method table */
7476#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007477
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007478#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007479
7480static PyObject *
7481build_times_result(double user, double system,
7482 double children_user, double children_system,
7483 double elapsed)
7484{
7485 PyObject *value = PyStructSequence_New(&TimesResultType);
7486 if (value == NULL)
7487 return NULL;
7488
7489#define SET(i, field) \
7490 { \
7491 PyObject *o = PyFloat_FromDouble(field); \
7492 if (!o) { \
7493 Py_DECREF(value); \
7494 return NULL; \
7495 } \
7496 PyStructSequence_SET_ITEM(value, i, o); \
7497 } \
7498
7499 SET(0, user);
7500 SET(1, system);
7501 SET(2, children_user);
7502 SET(3, children_system);
7503 SET(4, elapsed);
7504
7505#undef SET
7506
7507 return value;
7508}
7509
Larry Hastings605a62d2012-06-24 04:33:36 -07007510
Larry Hastings2f936352014-08-05 14:04:04 +10007511#ifndef MS_WINDOWS
7512#define NEED_TICKS_PER_SECOND
7513static long ticks_per_second = -1;
7514#endif /* MS_WINDOWS */
7515
7516/*[clinic input]
7517os.times
7518
7519Return a collection containing process timing information.
7520
7521The object returned behaves like a named tuple with these fields:
7522 (utime, stime, cutime, cstime, elapsed_time)
7523All fields are floating point numbers.
7524[clinic start generated code]*/
7525
Larry Hastings2f936352014-08-05 14:04:04 +10007526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007527os_times_impl(PyObject *module)
7528/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007529#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007530{
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 FILETIME create, exit, kernel, user;
7532 HANDLE hProc;
7533 hProc = GetCurrentProcess();
7534 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7535 /* The fields of a FILETIME structure are the hi and lo part
7536 of a 64-bit value expressed in 100 nanosecond units.
7537 1e7 is one second in such units; 1e-7 the inverse.
7538 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7539 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007540 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007541 (double)(user.dwHighDateTime*429.4967296 +
7542 user.dwLowDateTime*1e-7),
7543 (double)(kernel.dwHighDateTime*429.4967296 +
7544 kernel.dwLowDateTime*1e-7),
7545 (double)0,
7546 (double)0,
7547 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007548}
Larry Hastings2f936352014-08-05 14:04:04 +10007549#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007550{
Larry Hastings2f936352014-08-05 14:04:04 +10007551
7552
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007553 struct tms t;
7554 clock_t c;
7555 errno = 0;
7556 c = times(&t);
7557 if (c == (clock_t) -1)
7558 return posix_error();
7559 return build_times_result(
7560 (double)t.tms_utime / ticks_per_second,
7561 (double)t.tms_stime / ticks_per_second,
7562 (double)t.tms_cutime / ticks_per_second,
7563 (double)t.tms_cstime / ticks_per_second,
7564 (double)c / ticks_per_second);
7565}
Larry Hastings2f936352014-08-05 14:04:04 +10007566#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007567#endif /* HAVE_TIMES */
7568
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007569
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007570#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007571/*[clinic input]
7572os.getsid
7573
7574 pid: pid_t
7575 /
7576
7577Call the system call getsid(pid) and return the result.
7578[clinic start generated code]*/
7579
Larry Hastings2f936352014-08-05 14:04:04 +10007580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007581os_getsid_impl(PyObject *module, pid_t pid)
7582/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007583{
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007585 sid = getsid(pid);
7586 if (sid < 0)
7587 return posix_error();
7588 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007589}
7590#endif /* HAVE_GETSID */
7591
7592
Guido van Rossumb6775db1994-08-01 11:34:53 +00007593#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007594/*[clinic input]
7595os.setsid
7596
7597Call the system call setsid().
7598[clinic start generated code]*/
7599
Larry Hastings2f936352014-08-05 14:04:04 +10007600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007601os_setsid_impl(PyObject *module)
7602/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603{
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 if (setsid() < 0)
7605 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007606 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007607}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007608#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609
Larry Hastings2f936352014-08-05 14:04:04 +10007610
Guido van Rossumb6775db1994-08-01 11:34:53 +00007611#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007612/*[clinic input]
7613os.setpgid
7614
7615 pid: pid_t
7616 pgrp: pid_t
7617 /
7618
7619Call the system call setpgid(pid, pgrp).
7620[clinic start generated code]*/
7621
Larry Hastings2f936352014-08-05 14:04:04 +10007622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007623os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7624/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007625{
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 if (setpgid(pid, pgrp) < 0)
7627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007628 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007630#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007632
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007634/*[clinic input]
7635os.tcgetpgrp
7636
7637 fd: int
7638 /
7639
7640Return the process group associated with the terminal specified by fd.
7641[clinic start generated code]*/
7642
Larry Hastings2f936352014-08-05 14:04:04 +10007643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007644os_tcgetpgrp_impl(PyObject *module, int fd)
7645/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007646{
7647 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 if (pgid < 0)
7649 return posix_error();
7650 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007651}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007652#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007654
Guido van Rossumb6775db1994-08-01 11:34:53 +00007655#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007656/*[clinic input]
7657os.tcsetpgrp
7658
7659 fd: int
7660 pgid: pid_t
7661 /
7662
7663Set the process group associated with the terminal specified by fd.
7664[clinic start generated code]*/
7665
Larry Hastings2f936352014-08-05 14:04:04 +10007666static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007667os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7668/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007669{
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 if (tcsetpgrp(fd, pgid) < 0)
7671 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007672 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007673}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007674#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007675
Guido van Rossum687dd131993-05-17 08:34:16 +00007676/* Functions acting on file descriptors */
7677
Victor Stinnerdaf45552013-08-28 00:53:59 +02007678#ifdef O_CLOEXEC
7679extern int _Py_open_cloexec_works;
7680#endif
7681
Larry Hastings2f936352014-08-05 14:04:04 +10007682
7683/*[clinic input]
7684os.open -> int
7685 path: path_t
7686 flags: int
7687 mode: int = 0o777
7688 *
7689 dir_fd: dir_fd(requires='openat') = None
7690
7691# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7692
7693Open a file for low level IO. Returns a file descriptor (integer).
7694
7695If dir_fd is not None, it should be a file descriptor open to a directory,
7696 and path should be relative; path will then be relative to that directory.
7697dir_fd may not be implemented on your platform.
7698 If it is unavailable, using it will raise a NotImplementedError.
7699[clinic start generated code]*/
7700
Larry Hastings2f936352014-08-05 14:04:04 +10007701static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007702os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7703/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007704{
7705 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007706 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007707
Victor Stinnerdaf45552013-08-28 00:53:59 +02007708#ifdef O_CLOEXEC
7709 int *atomic_flag_works = &_Py_open_cloexec_works;
7710#elif !defined(MS_WINDOWS)
7711 int *atomic_flag_works = NULL;
7712#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007713
Victor Stinnerdaf45552013-08-28 00:53:59 +02007714#ifdef MS_WINDOWS
7715 flags |= O_NOINHERIT;
7716#elif defined(O_CLOEXEC)
7717 flags |= O_CLOEXEC;
7718#endif
7719
Steve Dower8fc89802015-04-12 00:26:27 -04007720 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007721 do {
7722 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007723#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007724 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007725#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007726#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 if (dir_fd != DEFAULT_DIR_FD)
7728 fd = openat(dir_fd, path->narrow, flags, mode);
7729 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007730#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007731 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007732#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007733 Py_END_ALLOW_THREADS
7734 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007735 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007736
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007737 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007738 if (!async_err)
7739 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007740 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007741 }
7742
Victor Stinnerdaf45552013-08-28 00:53:59 +02007743#ifndef MS_WINDOWS
7744 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7745 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007746 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007747 }
7748#endif
7749
Larry Hastings2f936352014-08-05 14:04:04 +10007750 return fd;
7751}
7752
7753
7754/*[clinic input]
7755os.close
7756
7757 fd: int
7758
7759Close a file descriptor.
7760[clinic start generated code]*/
7761
Barry Warsaw53699e91996-12-10 23:23:01 +00007762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007763os_close_impl(PyObject *module, int fd)
7764/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007765{
Larry Hastings2f936352014-08-05 14:04:04 +10007766 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007767 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7768 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7769 * for more details.
7770 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007771 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007772 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007774 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 Py_END_ALLOW_THREADS
7776 if (res < 0)
7777 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007778 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007779}
7780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007781
Larry Hastings2f936352014-08-05 14:04:04 +10007782/*[clinic input]
7783os.closerange
7784
7785 fd_low: int
7786 fd_high: int
7787 /
7788
7789Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7790[clinic start generated code]*/
7791
Larry Hastings2f936352014-08-05 14:04:04 +10007792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007793os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7794/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007795{
7796 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007798 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007799 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007800 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007801 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 Py_END_ALLOW_THREADS
7803 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007804}
7805
7806
Larry Hastings2f936352014-08-05 14:04:04 +10007807/*[clinic input]
7808os.dup -> int
7809
7810 fd: int
7811 /
7812
7813Return a duplicate of a file descriptor.
7814[clinic start generated code]*/
7815
Larry Hastings2f936352014-08-05 14:04:04 +10007816static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007817os_dup_impl(PyObject *module, int fd)
7818/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007819{
7820 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007821}
7822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007823
Larry Hastings2f936352014-08-05 14:04:04 +10007824/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007825os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007826 fd: int
7827 fd2: int
7828 inheritable: bool=True
7829
7830Duplicate file descriptor.
7831[clinic start generated code]*/
7832
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007833static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007834os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007835/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007836{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007837 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007838#if defined(HAVE_DUP3) && \
7839 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7840 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007841 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007842#endif
7843
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007844 if (fd < 0 || fd2 < 0) {
7845 posix_error();
7846 return -1;
7847 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007848
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007849 /* dup2() can fail with EINTR if the target FD is already open, because it
7850 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7851 * upon close(), and therefore below.
7852 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007853#ifdef MS_WINDOWS
7854 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007855 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007857 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007858 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007859 if (res < 0) {
7860 posix_error();
7861 return -1;
7862 }
7863 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007864
7865 /* Character files like console cannot be make non-inheritable */
7866 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7867 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007868 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007869 }
7870
7871#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7872 Py_BEGIN_ALLOW_THREADS
7873 if (!inheritable)
7874 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7875 else
7876 res = dup2(fd, fd2);
7877 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007878 if (res < 0) {
7879 posix_error();
7880 return -1;
7881 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007882
7883#else
7884
7885#ifdef HAVE_DUP3
7886 if (!inheritable && dup3_works != 0) {
7887 Py_BEGIN_ALLOW_THREADS
7888 res = dup3(fd, fd2, O_CLOEXEC);
7889 Py_END_ALLOW_THREADS
7890 if (res < 0) {
7891 if (dup3_works == -1)
7892 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007893 if (dup3_works) {
7894 posix_error();
7895 return -1;
7896 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007897 }
7898 }
7899
7900 if (inheritable || dup3_works == 0)
7901 {
7902#endif
7903 Py_BEGIN_ALLOW_THREADS
7904 res = dup2(fd, fd2);
7905 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007906 if (res < 0) {
7907 posix_error();
7908 return -1;
7909 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007910
7911 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7912 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007913 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007914 }
7915#ifdef HAVE_DUP3
7916 }
7917#endif
7918
7919#endif
7920
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007921 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007922}
7923
Larry Hastings2f936352014-08-05 14:04:04 +10007924
Ross Lagerwall7807c352011-03-17 20:20:30 +02007925#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007926/*[clinic input]
7927os.lockf
7928
7929 fd: int
7930 An open file descriptor.
7931 command: int
7932 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7933 length: Py_off_t
7934 The number of bytes to lock, starting at the current position.
7935 /
7936
7937Apply, test or remove a POSIX lock on an open file descriptor.
7938
7939[clinic start generated code]*/
7940
Larry Hastings2f936352014-08-05 14:04:04 +10007941static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007942os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7943/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007944{
7945 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007946
7947 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007948 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007949 Py_END_ALLOW_THREADS
7950
7951 if (res < 0)
7952 return posix_error();
7953
7954 Py_RETURN_NONE;
7955}
Larry Hastings2f936352014-08-05 14:04:04 +10007956#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007958
Larry Hastings2f936352014-08-05 14:04:04 +10007959/*[clinic input]
7960os.lseek -> Py_off_t
7961
7962 fd: int
7963 position: Py_off_t
7964 how: int
7965 /
7966
7967Set the position of a file descriptor. Return the new position.
7968
7969Return the new cursor position in number of bytes
7970relative to the beginning of the file.
7971[clinic start generated code]*/
7972
Larry Hastings2f936352014-08-05 14:04:04 +10007973static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007974os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7975/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007976{
7977 Py_off_t result;
7978
Guido van Rossum687dd131993-05-17 08:34:16 +00007979#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7981 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007982 case 0: how = SEEK_SET; break;
7983 case 1: how = SEEK_CUR; break;
7984 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007986#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007987
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007989 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007990
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007992 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007993#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007994 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007995#else
Larry Hastings2f936352014-08-05 14:04:04 +10007996 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007997#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007998 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008000 if (result < 0)
8001 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008002
Larry Hastings2f936352014-08-05 14:04:04 +10008003 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008004}
8005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008006
Larry Hastings2f936352014-08-05 14:04:04 +10008007/*[clinic input]
8008os.read
8009 fd: int
8010 length: Py_ssize_t
8011 /
8012
8013Read from a file descriptor. Returns a bytes object.
8014[clinic start generated code]*/
8015
Larry Hastings2f936352014-08-05 14:04:04 +10008016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008017os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8018/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008019{
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 Py_ssize_t n;
8021 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008022
8023 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 errno = EINVAL;
8025 return posix_error();
8026 }
Larry Hastings2f936352014-08-05 14:04:04 +10008027
Miss Islington (bot)18f33272018-11-22 06:17:34 -08008028 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008029
8030 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 if (buffer == NULL)
8032 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008033
Victor Stinner66aab0c2015-03-19 22:53:20 +01008034 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8035 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008037 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008038 }
Larry Hastings2f936352014-08-05 14:04:04 +10008039
8040 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008041 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008042
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008044}
8045
Ross Lagerwall7807c352011-03-17 20:20:30 +02008046#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008047 || defined(__APPLE__))) \
8048 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8049 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8050static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008051iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008052{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008053 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008054
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055 *iov = PyMem_New(struct iovec, cnt);
8056 if (*iov == NULL) {
8057 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008058 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008060
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 *buf = PyMem_New(Py_buffer, cnt);
8062 if (*buf == NULL) {
8063 PyMem_Del(*iov);
8064 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008065 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 }
8067
8068 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008069 PyObject *item = PySequence_GetItem(seq, i);
8070 if (item == NULL)
8071 goto fail;
8072 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8073 Py_DECREF(item);
8074 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008076 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008078 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008080 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008081
8082fail:
8083 PyMem_Del(*iov);
8084 for (j = 0; j < i; j++) {
8085 PyBuffer_Release(&(*buf)[j]);
8086 }
8087 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008088 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008089}
8090
8091static void
8092iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8093{
8094 int i;
8095 PyMem_Del(iov);
8096 for (i = 0; i < cnt; i++) {
8097 PyBuffer_Release(&buf[i]);
8098 }
8099 PyMem_Del(buf);
8100}
8101#endif
8102
Larry Hastings2f936352014-08-05 14:04:04 +10008103
Ross Lagerwall7807c352011-03-17 20:20:30 +02008104#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008105/*[clinic input]
8106os.readv -> Py_ssize_t
8107
8108 fd: int
8109 buffers: object
8110 /
8111
8112Read from a file descriptor fd into an iterable of buffers.
8113
8114The buffers should be mutable buffers accepting bytes.
8115readv will transfer data into each buffer until it is full
8116and then move on to the next buffer in the sequence to hold
8117the rest of the data.
8118
8119readv returns the total number of bytes read,
8120which may be less than the total capacity of all the buffers.
8121[clinic start generated code]*/
8122
Larry Hastings2f936352014-08-05 14:04:04 +10008123static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008124os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8125/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008126{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008127 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008128 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008129 struct iovec *iov;
8130 Py_buffer *buf;
8131
Larry Hastings2f936352014-08-05 14:04:04 +10008132 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133 PyErr_SetString(PyExc_TypeError,
8134 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008135 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008137
Larry Hastings2f936352014-08-05 14:04:04 +10008138 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008139 if (cnt < 0)
8140 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008141
8142 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8143 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008144
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008145 do {
8146 Py_BEGIN_ALLOW_THREADS
8147 n = readv(fd, iov, cnt);
8148 Py_END_ALLOW_THREADS
8149 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150
8151 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008152 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008153 if (!async_err)
8154 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008155 return -1;
8156 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008157
Larry Hastings2f936352014-08-05 14:04:04 +10008158 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008159}
Larry Hastings2f936352014-08-05 14:04:04 +10008160#endif /* HAVE_READV */
8161
Ross Lagerwall7807c352011-03-17 20:20:30 +02008162
8163#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008164/*[clinic input]
8165# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8166os.pread
8167
8168 fd: int
8169 length: int
8170 offset: Py_off_t
8171 /
8172
8173Read a number of bytes from a file descriptor starting at a particular offset.
8174
8175Read length bytes from file descriptor fd, starting at offset bytes from
8176the beginning of the file. The file offset remains unchanged.
8177[clinic start generated code]*/
8178
Larry Hastings2f936352014-08-05 14:04:04 +10008179static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008180os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8181/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008182{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008183 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008184 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008185 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008186
Larry Hastings2f936352014-08-05 14:04:04 +10008187 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008188 errno = EINVAL;
8189 return posix_error();
8190 }
Larry Hastings2f936352014-08-05 14:04:04 +10008191 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192 if (buffer == NULL)
8193 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008194
8195 do {
8196 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008197 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008198 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008199 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008200 Py_END_ALLOW_THREADS
8201 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8202
Ross Lagerwall7807c352011-03-17 20:20:30 +02008203 if (n < 0) {
8204 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008205 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008206 }
Larry Hastings2f936352014-08-05 14:04:04 +10008207 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208 _PyBytes_Resize(&buffer, n);
8209 return buffer;
8210}
Larry Hastings2f936352014-08-05 14:04:04 +10008211#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008212
Pablo Galindo4defba32018-01-27 16:16:37 +00008213#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8214/*[clinic input]
8215os.preadv -> Py_ssize_t
8216
8217 fd: int
8218 buffers: object
8219 offset: Py_off_t
8220 flags: int = 0
8221 /
8222
8223Reads from a file descriptor into a number of mutable bytes-like objects.
8224
8225Combines the functionality of readv() and pread(). As readv(), it will
8226transfer data into each buffer until it is full and then move on to the next
8227buffer in the sequence to hold the rest of the data. Its fourth argument,
8228specifies the file offset at which the input operation is to be performed. It
8229will return the total number of bytes read (which can be less than the total
8230capacity of all the objects).
8231
8232The flags argument contains a bitwise OR of zero or more of the following flags:
8233
8234- RWF_HIPRI
8235- RWF_NOWAIT
8236
8237Using non-zero flags requires Linux 4.6 or newer.
8238[clinic start generated code]*/
8239
8240static Py_ssize_t
8241os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8242 int flags)
8243/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8244{
8245 Py_ssize_t cnt, n;
8246 int async_err = 0;
8247 struct iovec *iov;
8248 Py_buffer *buf;
8249
8250 if (!PySequence_Check(buffers)) {
8251 PyErr_SetString(PyExc_TypeError,
8252 "preadv2() arg 2 must be a sequence");
8253 return -1;
8254 }
8255
8256 cnt = PySequence_Size(buffers);
8257 if (cnt < 0) {
8258 return -1;
8259 }
8260
8261#ifndef HAVE_PREADV2
8262 if(flags != 0) {
8263 argument_unavailable_error("preadv2", "flags");
8264 return -1;
8265 }
8266#endif
8267
8268 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8269 return -1;
8270 }
8271#ifdef HAVE_PREADV2
8272 do {
8273 Py_BEGIN_ALLOW_THREADS
8274 _Py_BEGIN_SUPPRESS_IPH
8275 n = preadv2(fd, iov, cnt, offset, flags);
8276 _Py_END_SUPPRESS_IPH
8277 Py_END_ALLOW_THREADS
8278 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8279#else
8280 do {
8281 Py_BEGIN_ALLOW_THREADS
8282 _Py_BEGIN_SUPPRESS_IPH
8283 n = preadv(fd, iov, cnt, offset);
8284 _Py_END_SUPPRESS_IPH
8285 Py_END_ALLOW_THREADS
8286 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8287#endif
8288
8289 iov_cleanup(iov, buf, cnt);
8290 if (n < 0) {
8291 if (!async_err) {
8292 posix_error();
8293 }
8294 return -1;
8295 }
8296
8297 return n;
8298}
8299#endif /* HAVE_PREADV */
8300
Larry Hastings2f936352014-08-05 14:04:04 +10008301
8302/*[clinic input]
8303os.write -> Py_ssize_t
8304
8305 fd: int
8306 data: Py_buffer
8307 /
8308
8309Write a bytes object to a file descriptor.
8310[clinic start generated code]*/
8311
Larry Hastings2f936352014-08-05 14:04:04 +10008312static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008313os_write_impl(PyObject *module, int fd, Py_buffer *data)
8314/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008315{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008316 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008317}
8318
8319#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008320PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008321"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008322sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008324Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325
Larry Hastings2f936352014-08-05 14:04:04 +10008326/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008327static PyObject *
8328posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8329{
8330 int in, out;
8331 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008332 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008333 off_t offset;
8334
8335#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8336#ifndef __APPLE__
8337 Py_ssize_t len;
8338#endif
8339 PyObject *headers = NULL, *trailers = NULL;
8340 Py_buffer *hbuf, *tbuf;
8341 off_t sbytes;
8342 struct sf_hdtr sf;
8343 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008344 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008345 static char *keywords[] = {"out", "in",
8346 "offset", "count",
8347 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008348
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008349 sf.headers = NULL;
8350 sf.trailers = NULL;
8351
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008352#ifdef __APPLE__
8353 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008354 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008355#else
8356 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008357 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008358#endif
8359 &headers, &trailers, &flags))
8360 return NULL;
8361 if (headers != NULL) {
8362 if (!PySequence_Check(headers)) {
8363 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008364 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008365 return NULL;
8366 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008367 Py_ssize_t i = PySequence_Size(headers);
8368 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008369 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008370 if (i > INT_MAX) {
8371 PyErr_SetString(PyExc_OverflowError,
8372 "sendfile() header is too large");
8373 return NULL;
8374 }
8375 if (i > 0) {
8376 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008377 if (iov_setup(&(sf.headers), &hbuf,
8378 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008379 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008380#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008381 for (i = 0; i < sf.hdr_cnt; i++) {
8382 Py_ssize_t blen = sf.headers[i].iov_len;
8383# define OFF_T_MAX 0x7fffffffffffffff
8384 if (sbytes >= OFF_T_MAX - blen) {
8385 PyErr_SetString(PyExc_OverflowError,
8386 "sendfile() header is too large");
8387 return NULL;
8388 }
8389 sbytes += blen;
8390 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008391#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008392 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008393 }
8394 }
8395 if (trailers != NULL) {
8396 if (!PySequence_Check(trailers)) {
8397 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008398 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008399 return NULL;
8400 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008401 Py_ssize_t i = PySequence_Size(trailers);
8402 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008403 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008404 if (i > INT_MAX) {
8405 PyErr_SetString(PyExc_OverflowError,
8406 "sendfile() trailer is too large");
8407 return NULL;
8408 }
8409 if (i > 0) {
8410 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008411 if (iov_setup(&(sf.trailers), &tbuf,
8412 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008413 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008414 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008415 }
8416 }
8417
Steve Dower8fc89802015-04-12 00:26:27 -04008418 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008419 do {
8420 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008421#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008423#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008424 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008425#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008426 Py_END_ALLOW_THREADS
8427 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008428 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008429
8430 if (sf.headers != NULL)
8431 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8432 if (sf.trailers != NULL)
8433 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8434
8435 if (ret < 0) {
8436 if ((errno == EAGAIN) || (errno == EBUSY)) {
8437 if (sbytes != 0) {
8438 // some data has been sent
8439 goto done;
8440 }
8441 else {
8442 // no data has been sent; upper application is supposed
8443 // to retry on EAGAIN or EBUSY
8444 return posix_error();
8445 }
8446 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008447 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008448 }
8449 goto done;
8450
8451done:
8452 #if !defined(HAVE_LARGEFILE_SUPPORT)
8453 return Py_BuildValue("l", sbytes);
8454 #else
8455 return Py_BuildValue("L", sbytes);
8456 #endif
8457
8458#else
8459 Py_ssize_t count;
8460 PyObject *offobj;
8461 static char *keywords[] = {"out", "in",
8462 "offset", "count", NULL};
8463 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8464 keywords, &out, &in, &offobj, &count))
8465 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008466#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008467 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008468 do {
8469 Py_BEGIN_ALLOW_THREADS
8470 ret = sendfile(out, in, NULL, count);
8471 Py_END_ALLOW_THREADS
8472 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008473 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008474 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008475 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008476 }
8477#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008478 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008479 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008480
8481 do {
8482 Py_BEGIN_ALLOW_THREADS
8483 ret = sendfile(out, in, &offset, count);
8484 Py_END_ALLOW_THREADS
8485 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008486 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008487 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008488 return Py_BuildValue("n", ret);
8489#endif
8490}
Larry Hastings2f936352014-08-05 14:04:04 +10008491#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008492
Larry Hastings2f936352014-08-05 14:04:04 +10008493
8494/*[clinic input]
8495os.fstat
8496
8497 fd : int
8498
8499Perform a stat system call on the given file descriptor.
8500
8501Like stat(), but for an open file descriptor.
8502Equivalent to os.stat(fd).
8503[clinic start generated code]*/
8504
Larry Hastings2f936352014-08-05 14:04:04 +10008505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008506os_fstat_impl(PyObject *module, int fd)
8507/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008508{
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 STRUCT_STAT st;
8510 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008511 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008512
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008513 do {
8514 Py_BEGIN_ALLOW_THREADS
8515 res = FSTAT(fd, &st);
8516 Py_END_ALLOW_THREADS
8517 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008519#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008520 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008521#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008522 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 }
Tim Peters5aa91602002-01-30 05:46:57 +00008525
Victor Stinner4195b5c2012-02-08 23:03:19 +01008526 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008527}
8528
Larry Hastings2f936352014-08-05 14:04:04 +10008529
8530/*[clinic input]
8531os.isatty -> bool
8532 fd: int
8533 /
8534
8535Return True if the fd is connected to a terminal.
8536
8537Return True if the file descriptor is an open file descriptor
8538connected to the slave end of a terminal.
8539[clinic start generated code]*/
8540
Larry Hastings2f936352014-08-05 14:04:04 +10008541static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008542os_isatty_impl(PyObject *module, int fd)
8543/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008544{
Steve Dower8fc89802015-04-12 00:26:27 -04008545 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008546 _Py_BEGIN_SUPPRESS_IPH
8547 return_value = isatty(fd);
8548 _Py_END_SUPPRESS_IPH
8549 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008550}
8551
8552
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008553#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008554/*[clinic input]
8555os.pipe
8556
8557Create a pipe.
8558
8559Returns a tuple of two file descriptors:
8560 (read_fd, write_fd)
8561[clinic start generated code]*/
8562
Larry Hastings2f936352014-08-05 14:04:04 +10008563static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008564os_pipe_impl(PyObject *module)
8565/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008566{
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008568#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008570 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008572#else
8573 int res;
8574#endif
8575
8576#ifdef MS_WINDOWS
8577 attr.nLength = sizeof(attr);
8578 attr.lpSecurityDescriptor = NULL;
8579 attr.bInheritHandle = FALSE;
8580
8581 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008582 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008583 ok = CreatePipe(&read, &write, &attr, 0);
8584 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008585 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8586 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008587 if (fds[0] == -1 || fds[1] == -1) {
8588 CloseHandle(read);
8589 CloseHandle(write);
8590 ok = 0;
8591 }
8592 }
Steve Dowerc3630612016-11-19 18:41:16 -08008593 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008594 Py_END_ALLOW_THREADS
8595
Victor Stinner8c62be82010-05-06 00:08:46 +00008596 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008597 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008598#else
8599
8600#ifdef HAVE_PIPE2
8601 Py_BEGIN_ALLOW_THREADS
8602 res = pipe2(fds, O_CLOEXEC);
8603 Py_END_ALLOW_THREADS
8604
8605 if (res != 0 && errno == ENOSYS)
8606 {
8607#endif
8608 Py_BEGIN_ALLOW_THREADS
8609 res = pipe(fds);
8610 Py_END_ALLOW_THREADS
8611
8612 if (res == 0) {
8613 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8614 close(fds[0]);
8615 close(fds[1]);
8616 return NULL;
8617 }
8618 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8619 close(fds[0]);
8620 close(fds[1]);
8621 return NULL;
8622 }
8623 }
8624#ifdef HAVE_PIPE2
8625 }
8626#endif
8627
8628 if (res != 0)
8629 return PyErr_SetFromErrno(PyExc_OSError);
8630#endif /* !MS_WINDOWS */
8631 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008632}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008633#endif /* HAVE_PIPE */
8634
Larry Hastings2f936352014-08-05 14:04:04 +10008635
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008636#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008637/*[clinic input]
8638os.pipe2
8639
8640 flags: int
8641 /
8642
8643Create a pipe with flags set atomically.
8644
8645Returns a tuple of two file descriptors:
8646 (read_fd, write_fd)
8647
8648flags can be constructed by ORing together one or more of these values:
8649O_NONBLOCK, O_CLOEXEC.
8650[clinic start generated code]*/
8651
Larry Hastings2f936352014-08-05 14:04:04 +10008652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008653os_pipe2_impl(PyObject *module, int flags)
8654/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008655{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008656 int fds[2];
8657 int res;
8658
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008659 res = pipe2(fds, flags);
8660 if (res != 0)
8661 return posix_error();
8662 return Py_BuildValue("(ii)", fds[0], fds[1]);
8663}
8664#endif /* HAVE_PIPE2 */
8665
Larry Hastings2f936352014-08-05 14:04:04 +10008666
Ross Lagerwall7807c352011-03-17 20:20:30 +02008667#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008668/*[clinic input]
8669os.writev -> Py_ssize_t
8670 fd: int
8671 buffers: object
8672 /
8673
8674Iterate over buffers, and write the contents of each to a file descriptor.
8675
8676Returns the total number of bytes written.
8677buffers must be a sequence of bytes-like objects.
8678[clinic start generated code]*/
8679
Larry Hastings2f936352014-08-05 14:04:04 +10008680static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008681os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8682/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008683{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008684 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008685 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008686 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008687 struct iovec *iov;
8688 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008689
8690 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008691 PyErr_SetString(PyExc_TypeError,
8692 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008693 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008694 }
Larry Hastings2f936352014-08-05 14:04:04 +10008695 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008696 if (cnt < 0)
8697 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008698
Larry Hastings2f936352014-08-05 14:04:04 +10008699 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8700 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008701 }
8702
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008703 do {
8704 Py_BEGIN_ALLOW_THREADS
8705 result = writev(fd, iov, cnt);
8706 Py_END_ALLOW_THREADS
8707 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008708
8709 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008710 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008711 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008712
Georg Brandl306336b2012-06-24 12:55:33 +02008713 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008714}
Larry Hastings2f936352014-08-05 14:04:04 +10008715#endif /* HAVE_WRITEV */
8716
8717
8718#ifdef HAVE_PWRITE
8719/*[clinic input]
8720os.pwrite -> Py_ssize_t
8721
8722 fd: int
8723 buffer: Py_buffer
8724 offset: Py_off_t
8725 /
8726
8727Write bytes to a file descriptor starting at a particular offset.
8728
8729Write buffer to fd, starting at offset bytes from the beginning of
8730the file. Returns the number of bytes writte. Does not change the
8731current file offset.
8732[clinic start generated code]*/
8733
Larry Hastings2f936352014-08-05 14:04:04 +10008734static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008735os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8736/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008737{
8738 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008739 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008740
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008741 do {
8742 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008743 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008744 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008745 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008746 Py_END_ALLOW_THREADS
8747 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008748
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008749 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008750 posix_error();
8751 return size;
8752}
8753#endif /* HAVE_PWRITE */
8754
Pablo Galindo4defba32018-01-27 16:16:37 +00008755#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8756/*[clinic input]
8757os.pwritev -> Py_ssize_t
8758
8759 fd: int
8760 buffers: object
8761 offset: Py_off_t
8762 flags: int = 0
8763 /
8764
8765Writes the contents of bytes-like objects to a file descriptor at a given offset.
8766
8767Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8768of bytes-like objects. Buffers are processed in array order. Entire contents of first
8769buffer is written before proceeding to second, and so on. The operating system may
8770set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8771This function writes the contents of each object to the file descriptor and returns
8772the total number of bytes written.
8773
8774The flags argument contains a bitwise OR of zero or more of the following flags:
8775
8776- RWF_DSYNC
8777- RWF_SYNC
8778
8779Using non-zero flags requires Linux 4.7 or newer.
8780[clinic start generated code]*/
8781
8782static Py_ssize_t
8783os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8784 int flags)
8785/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8786{
8787 Py_ssize_t cnt;
8788 Py_ssize_t result;
8789 int async_err = 0;
8790 struct iovec *iov;
8791 Py_buffer *buf;
8792
8793 if (!PySequence_Check(buffers)) {
8794 PyErr_SetString(PyExc_TypeError,
8795 "pwritev() arg 2 must be a sequence");
8796 return -1;
8797 }
8798
8799 cnt = PySequence_Size(buffers);
8800 if (cnt < 0) {
8801 return -1;
8802 }
8803
8804#ifndef HAVE_PWRITEV2
8805 if(flags != 0) {
8806 argument_unavailable_error("pwritev2", "flags");
8807 return -1;
8808 }
8809#endif
8810
8811 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8812 return -1;
8813 }
8814#ifdef HAVE_PWRITEV2
8815 do {
8816 Py_BEGIN_ALLOW_THREADS
8817 _Py_BEGIN_SUPPRESS_IPH
8818 result = pwritev2(fd, iov, cnt, offset, flags);
8819 _Py_END_SUPPRESS_IPH
8820 Py_END_ALLOW_THREADS
8821 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8822#else
8823 do {
8824 Py_BEGIN_ALLOW_THREADS
8825 _Py_BEGIN_SUPPRESS_IPH
8826 result = pwritev(fd, iov, cnt, offset);
8827 _Py_END_SUPPRESS_IPH
8828 Py_END_ALLOW_THREADS
8829 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8830#endif
8831
8832 iov_cleanup(iov, buf, cnt);
8833 if (result < 0) {
8834 if (!async_err) {
8835 posix_error();
8836 }
8837 return -1;
8838 }
8839
8840 return result;
8841}
8842#endif /* HAVE_PWRITEV */
8843
8844
8845
Larry Hastings2f936352014-08-05 14:04:04 +10008846
8847#ifdef HAVE_MKFIFO
8848/*[clinic input]
8849os.mkfifo
8850
8851 path: path_t
8852 mode: int=0o666
8853 *
8854 dir_fd: dir_fd(requires='mkfifoat')=None
8855
8856Create a "fifo" (a POSIX named pipe).
8857
8858If dir_fd is not None, it should be a file descriptor open to a directory,
8859 and path should be relative; path will then be relative to that directory.
8860dir_fd may not be implemented on your platform.
8861 If it is unavailable, using it will raise a NotImplementedError.
8862[clinic start generated code]*/
8863
Larry Hastings2f936352014-08-05 14:04:04 +10008864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008865os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8866/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008867{
8868 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008869 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008870
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008871 do {
8872 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008873#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008874 if (dir_fd != DEFAULT_DIR_FD)
8875 result = mkfifoat(dir_fd, path->narrow, mode);
8876 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008877#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008878 result = mkfifo(path->narrow, mode);
8879 Py_END_ALLOW_THREADS
8880 } while (result != 0 && errno == EINTR &&
8881 !(async_err = PyErr_CheckSignals()));
8882 if (result != 0)
8883 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008884
8885 Py_RETURN_NONE;
8886}
8887#endif /* HAVE_MKFIFO */
8888
8889
8890#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8891/*[clinic input]
8892os.mknod
8893
8894 path: path_t
8895 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008896 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008897 *
8898 dir_fd: dir_fd(requires='mknodat')=None
8899
8900Create a node in the file system.
8901
8902Create a node in the file system (file, device special file or named pipe)
8903at path. mode specifies both the permissions to use and the
8904type of node to be created, being combined (bitwise OR) with one of
8905S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8906device defines the newly created device special file (probably using
8907os.makedev()). Otherwise device is ignored.
8908
8909If dir_fd is not None, it should be a file descriptor open to a directory,
8910 and path should be relative; path will then be relative to that directory.
8911dir_fd may not be implemented on your platform.
8912 If it is unavailable, using it will raise a NotImplementedError.
8913[clinic start generated code]*/
8914
Larry Hastings2f936352014-08-05 14:04:04 +10008915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008916os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008917 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008918/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008919{
8920 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008921 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008922
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008923 do {
8924 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008925#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008926 if (dir_fd != DEFAULT_DIR_FD)
8927 result = mknodat(dir_fd, path->narrow, mode, device);
8928 else
Larry Hastings2f936352014-08-05 14:04:04 +10008929#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008930 result = mknod(path->narrow, mode, device);
8931 Py_END_ALLOW_THREADS
8932 } while (result != 0 && errno == EINTR &&
8933 !(async_err = PyErr_CheckSignals()));
8934 if (result != 0)
8935 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008936
8937 Py_RETURN_NONE;
8938}
8939#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8940
8941
8942#ifdef HAVE_DEVICE_MACROS
8943/*[clinic input]
8944os.major -> unsigned_int
8945
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008946 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008947 /
8948
8949Extracts a device major number from a raw device number.
8950[clinic start generated code]*/
8951
Larry Hastings2f936352014-08-05 14:04:04 +10008952static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008953os_major_impl(PyObject *module, dev_t device)
8954/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008955{
8956 return major(device);
8957}
8958
8959
8960/*[clinic input]
8961os.minor -> unsigned_int
8962
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008963 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008964 /
8965
8966Extracts a device minor number from a raw device number.
8967[clinic start generated code]*/
8968
Larry Hastings2f936352014-08-05 14:04:04 +10008969static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008970os_minor_impl(PyObject *module, dev_t device)
8971/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008972{
8973 return minor(device);
8974}
8975
8976
8977/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008978os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008979
8980 major: int
8981 minor: int
8982 /
8983
8984Composes a raw device number from the major and minor device numbers.
8985[clinic start generated code]*/
8986
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008987static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008988os_makedev_impl(PyObject *module, int major, int minor)
8989/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008990{
8991 return makedev(major, minor);
8992}
8993#endif /* HAVE_DEVICE_MACROS */
8994
8995
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008996#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008997/*[clinic input]
8998os.ftruncate
8999
9000 fd: int
9001 length: Py_off_t
9002 /
9003
9004Truncate a file, specified by file descriptor, to a specific length.
9005[clinic start generated code]*/
9006
Larry Hastings2f936352014-08-05 14:04:04 +10009007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009008os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9009/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009010{
9011 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009012 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009013
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009014 do {
9015 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009016 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009017#ifdef MS_WINDOWS
9018 result = _chsize_s(fd, length);
9019#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009020 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009021#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009022 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009023 Py_END_ALLOW_THREADS
9024 } while (result != 0 && errno == EINTR &&
9025 !(async_err = PyErr_CheckSignals()));
9026 if (result != 0)
9027 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009028 Py_RETURN_NONE;
9029}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009030#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009031
9032
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009033#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009034/*[clinic input]
9035os.truncate
9036 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9037 length: Py_off_t
9038
9039Truncate a file, specified by path, to a specific length.
9040
9041On some platforms, path may also be specified as an open file descriptor.
9042 If this functionality is unavailable, using it raises an exception.
9043[clinic start generated code]*/
9044
Larry Hastings2f936352014-08-05 14:04:04 +10009045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009046os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9047/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009048{
9049 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009050#ifdef MS_WINDOWS
9051 int fd;
9052#endif
9053
9054 if (path->fd != -1)
9055 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009056
9057 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009058 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009059#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009060 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009061 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009062 result = -1;
9063 else {
9064 result = _chsize_s(fd, length);
9065 close(fd);
9066 if (result < 0)
9067 errno = result;
9068 }
9069#else
9070 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009071#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009072 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009073 Py_END_ALLOW_THREADS
9074 if (result < 0)
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07009075 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009076
9077 Py_RETURN_NONE;
9078}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009079#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009080
Ross Lagerwall7807c352011-03-17 20:20:30 +02009081
Victor Stinnerd6b17692014-09-30 12:20:05 +02009082/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9083 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9084 defined, which is the case in Python on AIX. AIX bug report:
9085 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9086#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9087# define POSIX_FADVISE_AIX_BUG
9088#endif
9089
Victor Stinnerec39e262014-09-30 12:35:58 +02009090
Victor Stinnerd6b17692014-09-30 12:20:05 +02009091#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009092/*[clinic input]
9093os.posix_fallocate
9094
9095 fd: int
9096 offset: Py_off_t
9097 length: Py_off_t
9098 /
9099
9100Ensure a file has allocated at least a particular number of bytes on disk.
9101
9102Ensure that the file specified by fd encompasses a range of bytes
9103starting at offset bytes from the beginning and continuing for length bytes.
9104[clinic start generated code]*/
9105
Larry Hastings2f936352014-08-05 14:04:04 +10009106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009107os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009108 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009109/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009110{
9111 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009112 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009113
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009114 do {
9115 Py_BEGIN_ALLOW_THREADS
9116 result = posix_fallocate(fd, offset, length);
9117 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009118 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9119
9120 if (result == 0)
9121 Py_RETURN_NONE;
9122
9123 if (async_err)
9124 return NULL;
9125
9126 errno = result;
9127 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009128}
Victor Stinnerec39e262014-09-30 12:35:58 +02009129#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009130
Ross Lagerwall7807c352011-03-17 20:20:30 +02009131
Victor Stinnerd6b17692014-09-30 12:20:05 +02009132#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009133/*[clinic input]
9134os.posix_fadvise
9135
9136 fd: int
9137 offset: Py_off_t
9138 length: Py_off_t
9139 advice: int
9140 /
9141
9142Announce an intention to access data in a specific pattern.
9143
9144Announce an intention to access data in a specific pattern, thus allowing
9145the kernel to make optimizations.
9146The advice applies to the region of the file specified by fd starting at
9147offset and continuing for length bytes.
9148advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9149POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9150POSIX_FADV_DONTNEED.
9151[clinic start generated code]*/
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009154os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009155 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009156/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009157{
9158 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009159 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009160
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009161 do {
9162 Py_BEGIN_ALLOW_THREADS
9163 result = posix_fadvise(fd, offset, length, advice);
9164 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009165 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9166
9167 if (result == 0)
9168 Py_RETURN_NONE;
9169
9170 if (async_err)
9171 return NULL;
9172
9173 errno = result;
9174 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009175}
Victor Stinnerec39e262014-09-30 12:35:58 +02009176#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009177
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009178#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009179
Fred Drake762e2061999-08-26 17:23:54 +00009180/* Save putenv() parameters as values here, so we can collect them when they
9181 * get re-set with another call for the same key. */
9182static PyObject *posix_putenv_garbage;
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184static void
9185posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009186{
Larry Hastings2f936352014-08-05 14:04:04 +10009187 /* Install the first arg and newstr in posix_putenv_garbage;
9188 * this will cause previous value to be collected. This has to
9189 * happen after the real putenv() call because the old value
9190 * was still accessible until then. */
9191 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9192 /* really not much we can do; just leak */
9193 PyErr_Clear();
9194 else
9195 Py_DECREF(value);
9196}
9197
9198
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009199#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009200/*[clinic input]
9201os.putenv
9202
9203 name: unicode
9204 value: unicode
9205 /
9206
9207Change or add an environment variable.
9208[clinic start generated code]*/
9209
Larry Hastings2f936352014-08-05 14:04:04 +10009210static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009211os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9212/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009213{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009214 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009215 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009216
Serhiy Storchaka77703942017-06-25 07:33:01 +03009217 /* Search from index 1 because on Windows starting '=' is allowed for
9218 defining hidden environment variables. */
9219 if (PyUnicode_GET_LENGTH(name) == 0 ||
9220 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9221 {
9222 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9223 return NULL;
9224 }
Larry Hastings2f936352014-08-05 14:04:04 +10009225 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9226 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009227 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009228 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009229
9230 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9231 if (env == NULL)
9232 goto error;
9233 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009234 PyErr_Format(PyExc_ValueError,
9235 "the environment variable is longer than %u characters",
9236 _MAX_ENV);
9237 goto error;
9238 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009239 if (wcslen(env) != (size_t)size) {
9240 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009241 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009242 }
9243
Larry Hastings2f936352014-08-05 14:04:04 +10009244 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009246 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009248
Larry Hastings2f936352014-08-05 14:04:04 +10009249 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009250 Py_RETURN_NONE;
9251
9252error:
Larry Hastings2f936352014-08-05 14:04:04 +10009253 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009254 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009255}
Larry Hastings2f936352014-08-05 14:04:04 +10009256#else /* MS_WINDOWS */
9257/*[clinic input]
9258os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009259
Larry Hastings2f936352014-08-05 14:04:04 +10009260 name: FSConverter
9261 value: FSConverter
9262 /
9263
9264Change or add an environment variable.
9265[clinic start generated code]*/
9266
Larry Hastings2f936352014-08-05 14:04:04 +10009267static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009268os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9269/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009270{
9271 PyObject *bytes = NULL;
9272 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009273 const char *name_string = PyBytes_AS_STRING(name);
9274 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009275
Serhiy Storchaka77703942017-06-25 07:33:01 +03009276 if (strchr(name_string, '=') != NULL) {
9277 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9278 return NULL;
9279 }
Larry Hastings2f936352014-08-05 14:04:04 +10009280 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9281 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009282 return NULL;
9283 }
9284
9285 env = PyBytes_AS_STRING(bytes);
9286 if (putenv(env)) {
9287 Py_DECREF(bytes);
9288 return posix_error();
9289 }
9290
9291 posix_putenv_garbage_setitem(name, bytes);
9292 Py_RETURN_NONE;
9293}
9294#endif /* MS_WINDOWS */
9295#endif /* HAVE_PUTENV */
9296
9297
9298#ifdef HAVE_UNSETENV
9299/*[clinic input]
9300os.unsetenv
9301 name: FSConverter
9302 /
9303
9304Delete an environment variable.
9305[clinic start generated code]*/
9306
Larry Hastings2f936352014-08-05 14:04:04 +10009307static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009308os_unsetenv_impl(PyObject *module, PyObject *name)
9309/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009310{
Victor Stinner984890f2011-11-24 13:53:38 +01009311#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009312 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009313#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009314
Victor Stinner984890f2011-11-24 13:53:38 +01009315#ifdef HAVE_BROKEN_UNSETENV
9316 unsetenv(PyBytes_AS_STRING(name));
9317#else
Victor Stinner65170952011-11-22 22:16:17 +01009318 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009319 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009320 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009321#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009322
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 /* Remove the key from posix_putenv_garbage;
9324 * this will cause it to be collected. This has to
9325 * happen after the real unsetenv() call because the
9326 * old value was still accessible until then.
9327 */
Victor Stinner65170952011-11-22 22:16:17 +01009328 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 /* really not much we can do; just leak */
9330 PyErr_Clear();
9331 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009332 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009333}
Larry Hastings2f936352014-08-05 14:04:04 +10009334#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009335
Larry Hastings2f936352014-08-05 14:04:04 +10009336
9337/*[clinic input]
9338os.strerror
9339
9340 code: int
9341 /
9342
9343Translate an error code to a message string.
9344[clinic start generated code]*/
9345
Larry Hastings2f936352014-08-05 14:04:04 +10009346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009347os_strerror_impl(PyObject *module, int code)
9348/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009349{
9350 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 if (message == NULL) {
9352 PyErr_SetString(PyExc_ValueError,
9353 "strerror() argument out of range");
9354 return NULL;
9355 }
Victor Stinner1b579672011-12-17 05:47:23 +01009356 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009357}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009358
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009359
Guido van Rossumc9641791998-08-04 15:26:23 +00009360#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009361#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009362/*[clinic input]
9363os.WCOREDUMP -> bool
9364
9365 status: int
9366 /
9367
9368Return True if the process returning status was dumped to a core file.
9369[clinic start generated code]*/
9370
Larry Hastings2f936352014-08-05 14:04:04 +10009371static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009372os_WCOREDUMP_impl(PyObject *module, int status)
9373/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009374{
9375 WAIT_TYPE wait_status;
9376 WAIT_STATUS_INT(wait_status) = status;
9377 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009378}
9379#endif /* WCOREDUMP */
9380
Larry Hastings2f936352014-08-05 14:04:04 +10009381
Fred Drake106c1a02002-04-23 15:58:02 +00009382#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009383/*[clinic input]
9384os.WIFCONTINUED -> bool
9385
9386 status: int
9387
9388Return True if a particular process was continued from a job control stop.
9389
9390Return True if the process returning status was continued from a
9391job control stop.
9392[clinic start generated code]*/
9393
Larry Hastings2f936352014-08-05 14:04:04 +10009394static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009395os_WIFCONTINUED_impl(PyObject *module, int status)
9396/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009397{
9398 WAIT_TYPE wait_status;
9399 WAIT_STATUS_INT(wait_status) = status;
9400 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009401}
9402#endif /* WIFCONTINUED */
9403
Larry Hastings2f936352014-08-05 14:04:04 +10009404
Guido van Rossumc9641791998-08-04 15:26:23 +00009405#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009406/*[clinic input]
9407os.WIFSTOPPED -> bool
9408
9409 status: int
9410
9411Return True if the process returning status was stopped.
9412[clinic start generated code]*/
9413
Larry Hastings2f936352014-08-05 14:04:04 +10009414static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009415os_WIFSTOPPED_impl(PyObject *module, int status)
9416/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009417{
9418 WAIT_TYPE wait_status;
9419 WAIT_STATUS_INT(wait_status) = status;
9420 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009421}
9422#endif /* WIFSTOPPED */
9423
Larry Hastings2f936352014-08-05 14:04:04 +10009424
Guido van Rossumc9641791998-08-04 15:26:23 +00009425#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009426/*[clinic input]
9427os.WIFSIGNALED -> bool
9428
9429 status: int
9430
9431Return True if the process returning status was terminated by a signal.
9432[clinic start generated code]*/
9433
Larry Hastings2f936352014-08-05 14:04:04 +10009434static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009435os_WIFSIGNALED_impl(PyObject *module, int status)
9436/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009437{
9438 WAIT_TYPE wait_status;
9439 WAIT_STATUS_INT(wait_status) = status;
9440 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009441}
9442#endif /* WIFSIGNALED */
9443
Larry Hastings2f936352014-08-05 14:04:04 +10009444
Guido van Rossumc9641791998-08-04 15:26:23 +00009445#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009446/*[clinic input]
9447os.WIFEXITED -> bool
9448
9449 status: int
9450
9451Return True if the process returning status exited via the exit() system call.
9452[clinic start generated code]*/
9453
Larry Hastings2f936352014-08-05 14:04:04 +10009454static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009455os_WIFEXITED_impl(PyObject *module, int status)
9456/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009457{
9458 WAIT_TYPE wait_status;
9459 WAIT_STATUS_INT(wait_status) = status;
9460 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009461}
9462#endif /* WIFEXITED */
9463
Larry Hastings2f936352014-08-05 14:04:04 +10009464
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009465#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009466/*[clinic input]
9467os.WEXITSTATUS -> int
9468
9469 status: int
9470
9471Return the process return code from status.
9472[clinic start generated code]*/
9473
Larry Hastings2f936352014-08-05 14:04:04 +10009474static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009475os_WEXITSTATUS_impl(PyObject *module, int status)
9476/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009477{
9478 WAIT_TYPE wait_status;
9479 WAIT_STATUS_INT(wait_status) = status;
9480 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009481}
9482#endif /* WEXITSTATUS */
9483
Larry Hastings2f936352014-08-05 14:04:04 +10009484
Guido van Rossumc9641791998-08-04 15:26:23 +00009485#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009486/*[clinic input]
9487os.WTERMSIG -> int
9488
9489 status: int
9490
9491Return the signal that terminated the process that provided the status value.
9492[clinic start generated code]*/
9493
Larry Hastings2f936352014-08-05 14:04:04 +10009494static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009495os_WTERMSIG_impl(PyObject *module, int status)
9496/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009497{
9498 WAIT_TYPE wait_status;
9499 WAIT_STATUS_INT(wait_status) = status;
9500 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009501}
9502#endif /* WTERMSIG */
9503
Larry Hastings2f936352014-08-05 14:04:04 +10009504
Guido van Rossumc9641791998-08-04 15:26:23 +00009505#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009506/*[clinic input]
9507os.WSTOPSIG -> int
9508
9509 status: int
9510
9511Return the signal that stopped the process that provided the status value.
9512[clinic start generated code]*/
9513
Larry Hastings2f936352014-08-05 14:04:04 +10009514static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009515os_WSTOPSIG_impl(PyObject *module, int status)
9516/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009517{
9518 WAIT_TYPE wait_status;
9519 WAIT_STATUS_INT(wait_status) = status;
9520 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009521}
9522#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009523#endif /* HAVE_SYS_WAIT_H */
9524
9525
Thomas Wouters477c8d52006-05-27 19:21:47 +00009526#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009527#ifdef _SCO_DS
9528/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9529 needed definitions in sys/statvfs.h */
9530#define _SVID3
9531#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009532#include <sys/statvfs.h>
9533
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009534static PyObject*
9535_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9537 if (v == NULL)
9538 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009539
9540#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9542 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9543 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9544 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9545 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9546 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9547 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9548 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9549 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9550 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009551#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9553 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9554 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009555 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009557 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009559 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009561 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009563 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009565 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9567 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009568#endif
Michael Felt502d5512018-01-05 13:01:58 +01009569/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9570 * (issue #32390). */
9571#if defined(_AIX) && defined(_ALL_SOURCE)
9572 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9573#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009574 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009575#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009576 if (PyErr_Occurred()) {
9577 Py_DECREF(v);
9578 return NULL;
9579 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009580
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009582}
9583
Larry Hastings2f936352014-08-05 14:04:04 +10009584
9585/*[clinic input]
9586os.fstatvfs
9587 fd: int
9588 /
9589
9590Perform an fstatvfs system call on the given fd.
9591
9592Equivalent to statvfs(fd).
9593[clinic start generated code]*/
9594
Larry Hastings2f936352014-08-05 14:04:04 +10009595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009596os_fstatvfs_impl(PyObject *module, int fd)
9597/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009598{
9599 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009600 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009602
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009603 do {
9604 Py_BEGIN_ALLOW_THREADS
9605 result = fstatvfs(fd, &st);
9606 Py_END_ALLOW_THREADS
9607 } while (result != 0 && errno == EINTR &&
9608 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009609 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009610 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009611
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009613}
Larry Hastings2f936352014-08-05 14:04:04 +10009614#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009615
9616
Thomas Wouters477c8d52006-05-27 19:21:47 +00009617#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009618#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009619/*[clinic input]
9620os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009621
Larry Hastings2f936352014-08-05 14:04:04 +10009622 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9623
9624Perform a statvfs system call on the given path.
9625
9626path may always be specified as a string.
9627On some platforms, path may also be specified as an open file descriptor.
9628 If this functionality is unavailable, using it raises an exception.
9629[clinic start generated code]*/
9630
Larry Hastings2f936352014-08-05 14:04:04 +10009631static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009632os_statvfs_impl(PyObject *module, path_t *path)
9633/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009634{
9635 int result;
9636 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009637
9638 Py_BEGIN_ALLOW_THREADS
9639#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009640 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009641#ifdef __APPLE__
9642 /* handle weak-linking on Mac OS X 10.3 */
9643 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009644 fd_specified("statvfs", path->fd);
9645 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009646 }
9647#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009648 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009649 }
9650 else
9651#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009652 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009653 Py_END_ALLOW_THREADS
9654
9655 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009656 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009657 }
9658
Larry Hastings2f936352014-08-05 14:04:04 +10009659 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009660}
Larry Hastings2f936352014-08-05 14:04:04 +10009661#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9662
Guido van Rossum94f6f721999-01-06 18:42:14 +00009663
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009664#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009665/*[clinic input]
9666os._getdiskusage
9667
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009668 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009669
9670Return disk usage statistics about the given path as a (total, free) tuple.
9671[clinic start generated code]*/
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009674os__getdiskusage_impl(PyObject *module, path_t *path)
9675/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009676{
9677 BOOL retval;
9678 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009679
9680 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009681 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009682 Py_END_ALLOW_THREADS
9683 if (retval == 0)
9684 return PyErr_SetFromWindowsErr(0);
9685
9686 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9687}
Larry Hastings2f936352014-08-05 14:04:04 +10009688#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009689
9690
Fred Drakec9680921999-12-13 16:37:25 +00009691/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9692 * It maps strings representing configuration variable names to
9693 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009694 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009695 * rarely-used constants. There are three separate tables that use
9696 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009697 *
9698 * This code is always included, even if none of the interfaces that
9699 * need it are included. The #if hackery needed to avoid it would be
9700 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009701 */
9702struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009703 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009704 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009705};
9706
Fred Drake12c6e2d1999-12-14 21:25:03 +00009707static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009708conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009709 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009710{
Christian Heimes217cfd12007-12-02 14:31:20 +00009711 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009712 int value = _PyLong_AsInt(arg);
9713 if (value == -1 && PyErr_Occurred())
9714 return 0;
9715 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009716 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009717 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009718 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009719 /* look up the value in the table using a binary search */
9720 size_t lo = 0;
9721 size_t mid;
9722 size_t hi = tablesize;
9723 int cmp;
9724 const char *confname;
9725 if (!PyUnicode_Check(arg)) {
9726 PyErr_SetString(PyExc_TypeError,
9727 "configuration names must be strings or integers");
9728 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009730 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009731 if (confname == NULL)
9732 return 0;
9733 while (lo < hi) {
9734 mid = (lo + hi) / 2;
9735 cmp = strcmp(confname, table[mid].name);
9736 if (cmp < 0)
9737 hi = mid;
9738 else if (cmp > 0)
9739 lo = mid + 1;
9740 else {
9741 *valuep = table[mid].value;
9742 return 1;
9743 }
9744 }
9745 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9746 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009748}
9749
9750
9751#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9752static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009753#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009755#endif
9756#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009758#endif
Fred Drakec9680921999-12-13 16:37:25 +00009759#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009804#ifdef _PC_ACL_ENABLED
9805 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9806#endif
9807#ifdef _PC_MIN_HOLE_SIZE
9808 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9809#endif
9810#ifdef _PC_ALLOC_SIZE_MIN
9811 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9812#endif
9813#ifdef _PC_REC_INCR_XFER_SIZE
9814 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9815#endif
9816#ifdef _PC_REC_MAX_XFER_SIZE
9817 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9818#endif
9819#ifdef _PC_REC_MIN_XFER_SIZE
9820 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9821#endif
9822#ifdef _PC_REC_XFER_ALIGN
9823 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9824#endif
9825#ifdef _PC_SYMLINK_MAX
9826 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9827#endif
9828#ifdef _PC_XATTR_ENABLED
9829 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9830#endif
9831#ifdef _PC_XATTR_EXISTS
9832 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9833#endif
9834#ifdef _PC_TIMESTAMP_RESOLUTION
9835 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9836#endif
Fred Drakec9680921999-12-13 16:37:25 +00009837};
9838
Fred Drakec9680921999-12-13 16:37:25 +00009839static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009840conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009841{
9842 return conv_confname(arg, valuep, posix_constants_pathconf,
9843 sizeof(posix_constants_pathconf)
9844 / sizeof(struct constdef));
9845}
9846#endif
9847
Larry Hastings2f936352014-08-05 14:04:04 +10009848
Fred Drakec9680921999-12-13 16:37:25 +00009849#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009850/*[clinic input]
9851os.fpathconf -> long
9852
9853 fd: int
9854 name: path_confname
9855 /
9856
9857Return the configuration limit name for the file descriptor fd.
9858
9859If there is no limit, return -1.
9860[clinic start generated code]*/
9861
Larry Hastings2f936352014-08-05 14:04:04 +10009862static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009863os_fpathconf_impl(PyObject *module, int fd, int name)
9864/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009865{
9866 long limit;
9867
9868 errno = 0;
9869 limit = fpathconf(fd, name);
9870 if (limit == -1 && errno != 0)
9871 posix_error();
9872
9873 return limit;
9874}
9875#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009876
9877
9878#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009879/*[clinic input]
9880os.pathconf -> long
9881 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9882 name: path_confname
9883
9884Return the configuration limit name for the file or directory path.
9885
9886If there is no limit, return -1.
9887On some platforms, path may also be specified as an open file descriptor.
9888 If this functionality is unavailable, using it raises an exception.
9889[clinic start generated code]*/
9890
Larry Hastings2f936352014-08-05 14:04:04 +10009891static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009892os_pathconf_impl(PyObject *module, path_t *path, int name)
9893/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009894{
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009896
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009898#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009899 if (path->fd != -1)
9900 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009901 else
9902#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009903 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 if (limit == -1 && errno != 0) {
9905 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009906 /* could be a path or name problem */
9907 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009908 else
Larry Hastings2f936352014-08-05 14:04:04 +10009909 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 }
Larry Hastings2f936352014-08-05 14:04:04 +10009911
9912 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009913}
Larry Hastings2f936352014-08-05 14:04:04 +10009914#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009915
9916#ifdef HAVE_CONFSTR
9917static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009918#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009920#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009921#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009923#endif
9924#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009926#endif
Fred Draked86ed291999-12-15 15:34:33 +00009927#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009929#endif
9930#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009932#endif
9933#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009935#endif
9936#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009938#endif
Fred Drakec9680921999-12-13 16:37:25 +00009939#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
Fred Draked86ed291999-12-15 15:34:33 +00009963#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009965#endif
Fred Drakec9680921999-12-13 16:37:25 +00009966#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
Fred Draked86ed291999-12-15 15:34:33 +00009969#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009971#endif
9972#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009974#endif
9975#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009977#endif
9978#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009980#endif
Fred Drakec9680921999-12-13 16:37:25 +00009981#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
Fred Draked86ed291999-12-15 15:34:33 +000010029#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010031#endif
10032#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
10035#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010037#endif
10038#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010040#endif
10041#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010043#endif
10044#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010046#endif
10047#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010049#endif
10050#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010052#endif
10053#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010055#endif
10056#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010058#endif
10059#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010061#endif
10062#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010064#endif
10065#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010067#endif
Fred Drakec9680921999-12-13 16:37:25 +000010068};
10069
10070static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010071conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010072{
10073 return conv_confname(arg, valuep, posix_constants_confstr,
10074 sizeof(posix_constants_confstr)
10075 / sizeof(struct constdef));
10076}
10077
Larry Hastings2f936352014-08-05 14:04:04 +100010078
10079/*[clinic input]
10080os.confstr
10081
10082 name: confstr_confname
10083 /
10084
10085Return a string-valued system configuration variable.
10086[clinic start generated code]*/
10087
Larry Hastings2f936352014-08-05 14:04:04 +100010088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010089os_confstr_impl(PyObject *module, int name)
10090/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010091{
10092 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010093 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010094 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010095
Victor Stinnercb043522010-09-10 23:49:04 +000010096 errno = 0;
10097 len = confstr(name, buffer, sizeof(buffer));
10098 if (len == 0) {
10099 if (errno) {
10100 posix_error();
10101 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010102 }
10103 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010104 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010105 }
10106 }
Victor Stinnercb043522010-09-10 23:49:04 +000010107
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010108 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010109 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010110 char *buf = PyMem_Malloc(len);
10111 if (buf == NULL)
10112 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010113 len2 = confstr(name, buf, len);
10114 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010115 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010116 PyMem_Free(buf);
10117 }
10118 else
10119 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010120 return result;
10121}
Larry Hastings2f936352014-08-05 14:04:04 +100010122#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010123
10124
10125#ifdef HAVE_SYSCONF
10126static struct constdef posix_constants_sysconf[] = {
10127#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
Fred Draked86ed291999-12-15 15:34:33 +000010157#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010159#endif
10160#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010162#endif
Fred Drakec9680921999-12-13 16:37:25 +000010163#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
Fred Drakec9680921999-12-13 16:37:25 +000010166#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
Fred Draked86ed291999-12-15 15:34:33 +000010181#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010183#endif
Fred Drakec9680921999-12-13 16:37:25 +000010184#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
Fred Draked86ed291999-12-15 15:34:33 +000010199#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010201#endif
Fred Drakec9680921999-12-13 16:37:25 +000010202#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
Fred Draked86ed291999-12-15 15:34:33 +000010271#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
Fred Drakec9680921999-12-13 16:37:25 +000010274#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
Fred Draked86ed291999-12-15 15:34:33 +000010283#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010285#endif
Fred Drakec9680921999-12-13 16:37:25 +000010286#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
Fred Draked86ed291999-12-15 15:34:33 +000010289#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010291#endif
10292#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010294#endif
Fred Drakec9680921999-12-13 16:37:25 +000010295#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
Fred Draked86ed291999-12-15 15:34:33 +000010307#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010309#endif
Fred Drakec9680921999-12-13 16:37:25 +000010310#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
Fred Draked86ed291999-12-15 15:34:33 +000010331#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010333#endif
Fred Drakec9680921999-12-13 16:37:25 +000010334#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
Fred Draked86ed291999-12-15 15:34:33 +000010340#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010342#endif
Fred Drakec9680921999-12-13 16:37:25 +000010343#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
Fred Draked86ed291999-12-15 15:34:33 +000010370#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010372#endif
10373#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010375#endif
Fred Drakec9680921999-12-13 16:37:25 +000010376#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
10430#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010432#endif
10433#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
10448#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010450#endif
10451#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010453#endif
10454#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010456#endif
10457#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010459#endif
10460#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010462#endif
10463#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010465#endif
10466#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010468#endif
10469#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010471#endif
10472#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010474#endif
10475#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010477#endif
10478#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010480#endif
Fred Draked86ed291999-12-15 15:34:33 +000010481#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010483#endif
Fred Drakec9680921999-12-13 16:37:25 +000010484#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
10511#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010513#endif
10514#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
10517#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010519#endif
10520#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010522#endif
10523#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010525#endif
10526#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010528#endif
10529#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010531#endif
10532#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010534#endif
10535#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010537#endif
10538#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010540#endif
10541#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010543#endif
10544#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010546#endif
10547#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
10577#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010579#endif
10580#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010582#endif
10583#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010585#endif
10586#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010588#endif
10589#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010591#endif
10592#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010594#endif
10595#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010597#endif
10598#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010600#endif
10601#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010603#endif
10604#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010606#endif
10607#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010609#endif
10610#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010612#endif
10613#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010615#endif
10616#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010618#endif
10619};
10620
10621static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010622conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010623{
10624 return conv_confname(arg, valuep, posix_constants_sysconf,
10625 sizeof(posix_constants_sysconf)
10626 / sizeof(struct constdef));
10627}
10628
Larry Hastings2f936352014-08-05 14:04:04 +100010629
10630/*[clinic input]
10631os.sysconf -> long
10632 name: sysconf_confname
10633 /
10634
10635Return an integer-valued system configuration variable.
10636[clinic start generated code]*/
10637
Larry Hastings2f936352014-08-05 14:04:04 +100010638static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010639os_sysconf_impl(PyObject *module, int name)
10640/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010641{
10642 long value;
10643
10644 errno = 0;
10645 value = sysconf(name);
10646 if (value == -1 && errno != 0)
10647 posix_error();
10648 return value;
10649}
10650#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010651
10652
Fred Drakebec628d1999-12-15 18:31:10 +000010653/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010654 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010655 * the exported dictionaries that are used to publish information about the
10656 * names available on the host platform.
10657 *
10658 * Sorting the table at runtime ensures that the table is properly ordered
10659 * when used, even for platforms we're not able to test on. It also makes
10660 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010661 */
Fred Drakebec628d1999-12-15 18:31:10 +000010662
10663static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010664cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010665{
10666 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010668 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010670
10671 return strcmp(c1->name, c2->name);
10672}
10673
10674static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010675setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010676 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010677{
Fred Drakebec628d1999-12-15 18:31:10 +000010678 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010679 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010680
10681 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10682 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010683 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010685
Barry Warsaw3155db32000-04-13 15:20:40 +000010686 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 PyObject *o = PyLong_FromLong(table[i].value);
10688 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10689 Py_XDECREF(o);
10690 Py_DECREF(d);
10691 return -1;
10692 }
10693 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010694 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010695 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010696}
10697
Fred Drakebec628d1999-12-15 18:31:10 +000010698/* Return -1 on failure, 0 on success. */
10699static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010700setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010701{
10702#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010703 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010704 sizeof(posix_constants_pathconf)
10705 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010706 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010707 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010708#endif
10709#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010710 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010711 sizeof(posix_constants_confstr)
10712 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010713 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010714 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010715#endif
10716#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010717 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010718 sizeof(posix_constants_sysconf)
10719 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010720 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010721 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010722#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010723 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010724}
Fred Draked86ed291999-12-15 15:34:33 +000010725
10726
Larry Hastings2f936352014-08-05 14:04:04 +100010727/*[clinic input]
10728os.abort
10729
10730Abort the interpreter immediately.
10731
10732This function 'dumps core' or otherwise fails in the hardest way possible
10733on the hosting operating system. This function never returns.
10734[clinic start generated code]*/
10735
Larry Hastings2f936352014-08-05 14:04:04 +100010736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010737os_abort_impl(PyObject *module)
10738/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010739{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010740 abort();
10741 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010742#ifndef __clang__
10743 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10744 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10745 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010746 Py_FatalError("abort() called from Python code didn't abort!");
10747 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010748#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010749}
Fred Drakebec628d1999-12-15 18:31:10 +000010750
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010751#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010752/* Grab ShellExecute dynamically from shell32 */
10753static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010754static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10755 LPCWSTR, INT);
10756static int
10757check_ShellExecute()
10758{
10759 HINSTANCE hShell32;
10760
10761 /* only recheck */
10762 if (-1 == has_ShellExecute) {
10763 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010764 /* Security note: this call is not vulnerable to "DLL hijacking".
10765 SHELL32 is part of "KnownDLLs" and so Windows always load
10766 the system SHELL32.DLL, even if there is another SHELL32.DLL
10767 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010768 hShell32 = LoadLibraryW(L"SHELL32");
10769 Py_END_ALLOW_THREADS
10770 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010771 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10772 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010773 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010774 } else {
10775 has_ShellExecute = 0;
10776 }
10777 }
10778 return has_ShellExecute;
10779}
10780
10781
Steve Dowercc16be82016-09-08 10:35:16 -070010782/*[clinic input]
10783os.startfile
10784 filepath: path_t
10785 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010786
Steve Dowercc16be82016-09-08 10:35:16 -070010787startfile(filepath [, operation])
10788
10789Start a file with its associated application.
10790
10791When "operation" is not specified or "open", this acts like
10792double-clicking the file in Explorer, or giving the file name as an
10793argument to the DOS "start" command: the file is opened with whatever
10794application (if any) its extension is associated.
10795When another "operation" is given, it specifies what should be done with
10796the file. A typical operation is "print".
10797
10798startfile returns as soon as the associated application is launched.
10799There is no option to wait for the application to close, and no way
10800to retrieve the application's exit status.
10801
10802The filepath is relative to the current directory. If you want to use
10803an absolute path, make sure the first character is not a slash ("/");
10804the underlying Win32 ShellExecute function doesn't work if it is.
10805[clinic start generated code]*/
10806
10807static PyObject *
Serhiy Storchaka45a7b762018-12-14 11:56:48 +020010808os_startfile_impl(PyObject *module, path_t *filepath,
10809 const Py_UNICODE *operation)
10810/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070010811{
10812 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010813
10814 if(!check_ShellExecute()) {
10815 /* If the OS doesn't have ShellExecute, return a
10816 NotImplementedError. */
10817 return PyErr_Format(PyExc_NotImplementedError,
10818 "startfile not available on this platform");
10819 }
10820
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010822 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010823 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 Py_END_ALLOW_THREADS
10825
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010827 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010828 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 }
Steve Dowercc16be82016-09-08 10:35:16 -070010830 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010831}
Larry Hastings2f936352014-08-05 14:04:04 +100010832#endif /* MS_WINDOWS */
10833
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010834
Martin v. Löwis438b5342002-12-27 10:16:42 +000010835#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010836/*[clinic input]
10837os.getloadavg
10838
10839Return average recent system load information.
10840
10841Return the number of processes in the system run queue averaged over
10842the last 1, 5, and 15 minutes as a tuple of three floats.
10843Raises OSError if the load average was unobtainable.
10844[clinic start generated code]*/
10845
Larry Hastings2f936352014-08-05 14:04:04 +100010846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010847os_getloadavg_impl(PyObject *module)
10848/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010849{
10850 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010851 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010852 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10853 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010854 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010855 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010856}
Larry Hastings2f936352014-08-05 14:04:04 +100010857#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010858
Larry Hastings2f936352014-08-05 14:04:04 +100010859
10860/*[clinic input]
10861os.device_encoding
10862 fd: int
10863
10864Return a string describing the encoding of a terminal's file descriptor.
10865
10866The file descriptor must be attached to a terminal.
10867If the device is not a terminal, return None.
10868[clinic start generated code]*/
10869
Larry Hastings2f936352014-08-05 14:04:04 +100010870static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010871os_device_encoding_impl(PyObject *module, int fd)
10872/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010873{
Brett Cannonefb00c02012-02-29 18:31:31 -050010874 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010875}
10876
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010877
Larry Hastings2f936352014-08-05 14:04:04 +100010878#ifdef HAVE_SETRESUID
10879/*[clinic input]
10880os.setresuid
10881
10882 ruid: uid_t
10883 euid: uid_t
10884 suid: uid_t
10885 /
10886
10887Set the current process's real, effective, and saved user ids.
10888[clinic start generated code]*/
10889
Larry Hastings2f936352014-08-05 14:04:04 +100010890static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010891os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10892/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010893{
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 if (setresuid(ruid, euid, suid) < 0)
10895 return posix_error();
10896 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010897}
Larry Hastings2f936352014-08-05 14:04:04 +100010898#endif /* HAVE_SETRESUID */
10899
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010900
10901#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010902/*[clinic input]
10903os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010904
Larry Hastings2f936352014-08-05 14:04:04 +100010905 rgid: gid_t
10906 egid: gid_t
10907 sgid: gid_t
10908 /
10909
10910Set the current process's real, effective, and saved group ids.
10911[clinic start generated code]*/
10912
Larry Hastings2f936352014-08-05 14:04:04 +100010913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010914os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10915/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010916{
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 if (setresgid(rgid, egid, sgid) < 0)
10918 return posix_error();
10919 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010920}
Larry Hastings2f936352014-08-05 14:04:04 +100010921#endif /* HAVE_SETRESGID */
10922
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010923
10924#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010925/*[clinic input]
10926os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010927
Larry Hastings2f936352014-08-05 14:04:04 +100010928Return a tuple of the current process's real, effective, and saved user ids.
10929[clinic start generated code]*/
10930
Larry Hastings2f936352014-08-05 14:04:04 +100010931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010932os_getresuid_impl(PyObject *module)
10933/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010934{
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 if (getresuid(&ruid, &euid, &suid) < 0)
10937 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010938 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10939 _PyLong_FromUid(euid),
10940 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010941}
Larry Hastings2f936352014-08-05 14:04:04 +100010942#endif /* HAVE_GETRESUID */
10943
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010944
10945#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010946/*[clinic input]
10947os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010948
Larry Hastings2f936352014-08-05 14:04:04 +100010949Return a tuple of the current process's real, effective, and saved group ids.
10950[clinic start generated code]*/
10951
Larry Hastings2f936352014-08-05 14:04:04 +100010952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010953os_getresgid_impl(PyObject *module)
10954/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010955{
10956 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 if (getresgid(&rgid, &egid, &sgid) < 0)
10958 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010959 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10960 _PyLong_FromGid(egid),
10961 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010962}
Larry Hastings2f936352014-08-05 14:04:04 +100010963#endif /* HAVE_GETRESGID */
10964
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010965
Benjamin Peterson9428d532011-09-14 11:45:52 -040010966#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010967/*[clinic input]
10968os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010969
Larry Hastings2f936352014-08-05 14:04:04 +100010970 path: path_t(allow_fd=True)
10971 attribute: path_t
10972 *
10973 follow_symlinks: bool = True
10974
10975Return the value of extended attribute attribute on path.
10976
BNMetrics08026b12018-11-02 17:56:25 +000010977path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100010978If follow_symlinks is False, and the last element of the path is a symbolic
10979 link, getxattr will examine the symbolic link itself instead of the file
10980 the link points to.
10981
10982[clinic start generated code]*/
10983
Larry Hastings2f936352014-08-05 14:04:04 +100010984static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010985os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010986 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000010987/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010988{
10989 Py_ssize_t i;
10990 PyObject *buffer = NULL;
10991
10992 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10993 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010994
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 for (i = 0; ; i++) {
10996 void *ptr;
10997 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010998 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010999 Py_ssize_t buffer_size = buffer_sizes[i];
11000 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011001 path_error(path);
11002 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011003 }
11004 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11005 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011006 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011008
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011010 if (path->fd >= 0)
11011 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011012 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011013 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011014 else
Larry Hastings2f936352014-08-05 14:04:04 +100011015 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011016 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011017
Larry Hastings9cf065c2012-06-22 16:30:09 -070011018 if (result < 0) {
11019 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 if (errno == ERANGE)
11021 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011022 path_error(path);
11023 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011024 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011025
Larry Hastings9cf065c2012-06-22 16:30:09 -070011026 if (result != buffer_size) {
11027 /* Can only shrink. */
11028 _PyBytes_Resize(&buffer, result);
11029 }
11030 break;
11031 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011032
Larry Hastings9cf065c2012-06-22 16:30:09 -070011033 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011034}
11035
Larry Hastings2f936352014-08-05 14:04:04 +100011036
11037/*[clinic input]
11038os.setxattr
11039
11040 path: path_t(allow_fd=True)
11041 attribute: path_t
11042 value: Py_buffer
11043 flags: int = 0
11044 *
11045 follow_symlinks: bool = True
11046
11047Set extended attribute attribute on path to value.
11048
BNMetrics08026b12018-11-02 17:56:25 +000011049path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011050If follow_symlinks is False, and the last element of the path is a symbolic
11051 link, setxattr will modify the symbolic link itself instead of the file
11052 the link points to.
11053
11054[clinic start generated code]*/
11055
Benjamin Peterson799bd802011-08-31 22:15:17 -040011056static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011057os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011058 Py_buffer *value, int flags, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011059/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011060{
Larry Hastings2f936352014-08-05 14:04:04 +100011061 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011062
Larry Hastings2f936352014-08-05 14:04:04 +100011063 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011064 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011065
Benjamin Peterson799bd802011-08-31 22:15:17 -040011066 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011067 if (path->fd > -1)
11068 result = fsetxattr(path->fd, attribute->narrow,
11069 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011070 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011071 result = setxattr(path->narrow, attribute->narrow,
11072 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011073 else
Larry Hastings2f936352014-08-05 14:04:04 +100011074 result = lsetxattr(path->narrow, attribute->narrow,
11075 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011076 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011077
Larry Hastings9cf065c2012-06-22 16:30:09 -070011078 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011079 path_error(path);
11080 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011081 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011082
Larry Hastings2f936352014-08-05 14:04:04 +100011083 Py_RETURN_NONE;
11084}
11085
11086
11087/*[clinic input]
11088os.removexattr
11089
11090 path: path_t(allow_fd=True)
11091 attribute: path_t
11092 *
11093 follow_symlinks: bool = True
11094
11095Remove extended attribute attribute on path.
11096
BNMetrics08026b12018-11-02 17:56:25 +000011097path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011098If follow_symlinks is False, and the last element of the path is a symbolic
11099 link, removexattr will modify the symbolic link itself instead of the file
11100 the link points to.
11101
11102[clinic start generated code]*/
11103
Larry Hastings2f936352014-08-05 14:04:04 +100011104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011105os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011106 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011107/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011108{
11109 ssize_t result;
11110
11111 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11112 return NULL;
11113
11114 Py_BEGIN_ALLOW_THREADS;
11115 if (path->fd > -1)
11116 result = fremovexattr(path->fd, attribute->narrow);
11117 else if (follow_symlinks)
11118 result = removexattr(path->narrow, attribute->narrow);
11119 else
11120 result = lremovexattr(path->narrow, attribute->narrow);
11121 Py_END_ALLOW_THREADS;
11122
11123 if (result) {
11124 return path_error(path);
11125 }
11126
11127 Py_RETURN_NONE;
11128}
11129
11130
11131/*[clinic input]
11132os.listxattr
11133
11134 path: path_t(allow_fd=True, nullable=True) = None
11135 *
11136 follow_symlinks: bool = True
11137
11138Return a list of extended attributes on path.
11139
BNMetrics08026b12018-11-02 17:56:25 +000011140path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011141if path is None, listxattr will examine the current directory.
11142If follow_symlinks is False, and the last element of the path is a symbolic
11143 link, listxattr will examine the symbolic link itself instead of the file
11144 the link points to.
11145[clinic start generated code]*/
11146
Larry Hastings2f936352014-08-05 14:04:04 +100011147static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011148os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011149/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011150{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011151 Py_ssize_t i;
11152 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011153 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011154 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011155
Larry Hastings2f936352014-08-05 14:04:04 +100011156 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011157 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011158
Larry Hastings2f936352014-08-05 14:04:04 +100011159 name = path->narrow ? path->narrow : ".";
11160
Larry Hastings9cf065c2012-06-22 16:30:09 -070011161 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011162 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011163 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011164 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011165 Py_ssize_t buffer_size = buffer_sizes[i];
11166 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011167 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011168 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011169 break;
11170 }
11171 buffer = PyMem_MALLOC(buffer_size);
11172 if (!buffer) {
11173 PyErr_NoMemory();
11174 break;
11175 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011176
Larry Hastings9cf065c2012-06-22 16:30:09 -070011177 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011178 if (path->fd > -1)
11179 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011180 else if (follow_symlinks)
11181 length = listxattr(name, buffer, buffer_size);
11182 else
11183 length = llistxattr(name, buffer, buffer_size);
11184 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011185
Larry Hastings9cf065c2012-06-22 16:30:09 -070011186 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011187 if (errno == ERANGE) {
11188 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011189 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011190 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011191 }
Larry Hastings2f936352014-08-05 14:04:04 +100011192 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011193 break;
11194 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011195
Larry Hastings9cf065c2012-06-22 16:30:09 -070011196 result = PyList_New(0);
11197 if (!result) {
11198 goto exit;
11199 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011200
Larry Hastings9cf065c2012-06-22 16:30:09 -070011201 end = buffer + length;
11202 for (trace = start = buffer; trace != end; trace++) {
11203 if (!*trace) {
11204 int error;
11205 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11206 trace - start);
11207 if (!attribute) {
11208 Py_DECREF(result);
11209 result = NULL;
11210 goto exit;
11211 }
11212 error = PyList_Append(result, attribute);
11213 Py_DECREF(attribute);
11214 if (error) {
11215 Py_DECREF(result);
11216 result = NULL;
11217 goto exit;
11218 }
11219 start = trace + 1;
11220 }
11221 }
11222 break;
11223 }
11224exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011225 if (buffer)
11226 PyMem_FREE(buffer);
11227 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011228}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011229#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011230
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011231
Larry Hastings2f936352014-08-05 14:04:04 +100011232/*[clinic input]
11233os.urandom
11234
11235 size: Py_ssize_t
11236 /
11237
11238Return a bytes object containing random bytes suitable for cryptographic use.
11239[clinic start generated code]*/
11240
Larry Hastings2f936352014-08-05 14:04:04 +100011241static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011242os_urandom_impl(PyObject *module, Py_ssize_t size)
11243/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011244{
11245 PyObject *bytes;
11246 int result;
11247
Georg Brandl2fb477c2012-02-21 00:33:36 +010011248 if (size < 0)
11249 return PyErr_Format(PyExc_ValueError,
11250 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011251 bytes = PyBytes_FromStringAndSize(NULL, size);
11252 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011253 return NULL;
11254
Victor Stinnere66987e2016-09-06 16:33:52 -070011255 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011256 if (result == -1) {
11257 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011258 return NULL;
11259 }
Larry Hastings2f936352014-08-05 14:04:04 +100011260 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011261}
11262
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011263/* Terminal size querying */
11264
11265static PyTypeObject TerminalSizeType;
11266
11267PyDoc_STRVAR(TerminalSize_docstring,
11268 "A tuple of (columns, lines) for holding terminal window size");
11269
11270static PyStructSequence_Field TerminalSize_fields[] = {
11271 {"columns", "width of the terminal window in characters"},
11272 {"lines", "height of the terminal window in characters"},
11273 {NULL, NULL}
11274};
11275
11276static PyStructSequence_Desc TerminalSize_desc = {
11277 "os.terminal_size",
11278 TerminalSize_docstring,
11279 TerminalSize_fields,
11280 2,
11281};
11282
11283#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011284/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011285PyDoc_STRVAR(termsize__doc__,
11286 "Return the size of the terminal window as (columns, lines).\n" \
11287 "\n" \
11288 "The optional argument fd (default standard output) specifies\n" \
11289 "which file descriptor should be queried.\n" \
11290 "\n" \
11291 "If the file descriptor is not connected to a terminal, an OSError\n" \
11292 "is thrown.\n" \
11293 "\n" \
11294 "This function will only be defined if an implementation is\n" \
11295 "available for this system.\n" \
11296 "\n" \
11297 "shutil.get_terminal_size is the high-level function which should \n" \
11298 "normally be used, os.get_terminal_size is the low-level implementation.");
11299
11300static PyObject*
11301get_terminal_size(PyObject *self, PyObject *args)
11302{
11303 int columns, lines;
11304 PyObject *termsize;
11305
11306 int fd = fileno(stdout);
11307 /* Under some conditions stdout may not be connected and
11308 * fileno(stdout) may point to an invalid file descriptor. For example
11309 * GUI apps don't have valid standard streams by default.
11310 *
11311 * If this happens, and the optional fd argument is not present,
11312 * the ioctl below will fail returning EBADF. This is what we want.
11313 */
11314
11315 if (!PyArg_ParseTuple(args, "|i", &fd))
11316 return NULL;
11317
11318#ifdef TERMSIZE_USE_IOCTL
11319 {
11320 struct winsize w;
11321 if (ioctl(fd, TIOCGWINSZ, &w))
11322 return PyErr_SetFromErrno(PyExc_OSError);
11323 columns = w.ws_col;
11324 lines = w.ws_row;
11325 }
11326#endif /* TERMSIZE_USE_IOCTL */
11327
11328#ifdef TERMSIZE_USE_CONIO
11329 {
11330 DWORD nhandle;
11331 HANDLE handle;
11332 CONSOLE_SCREEN_BUFFER_INFO csbi;
11333 switch (fd) {
11334 case 0: nhandle = STD_INPUT_HANDLE;
11335 break;
11336 case 1: nhandle = STD_OUTPUT_HANDLE;
11337 break;
11338 case 2: nhandle = STD_ERROR_HANDLE;
11339 break;
11340 default:
11341 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11342 }
11343 handle = GetStdHandle(nhandle);
11344 if (handle == NULL)
11345 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11346 if (handle == INVALID_HANDLE_VALUE)
11347 return PyErr_SetFromWindowsErr(0);
11348
11349 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11350 return PyErr_SetFromWindowsErr(0);
11351
11352 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11353 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11354 }
11355#endif /* TERMSIZE_USE_CONIO */
11356
11357 termsize = PyStructSequence_New(&TerminalSizeType);
11358 if (termsize == NULL)
11359 return NULL;
11360 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11361 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11362 if (PyErr_Occurred()) {
11363 Py_DECREF(termsize);
11364 return NULL;
11365 }
11366 return termsize;
11367}
11368#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11369
Larry Hastings2f936352014-08-05 14:04:04 +100011370
11371/*[clinic input]
11372os.cpu_count
11373
Charles-François Natali80d62e62015-08-13 20:37:08 +010011374Return the number of CPUs in the system; return None if indeterminable.
11375
11376This number is not equivalent to the number of CPUs the current process can
11377use. The number of usable CPUs can be obtained with
11378``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011379[clinic start generated code]*/
11380
Larry Hastings2f936352014-08-05 14:04:04 +100011381static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011382os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011383/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011384{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011385 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011386#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011387 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11388 Need to fallback to Vista behavior if this call isn't present */
11389 HINSTANCE hKernel32;
11390 hKernel32 = GetModuleHandleW(L"KERNEL32");
11391
11392 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11393 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11394 "GetMaximumProcessorCount");
11395 if (_GetMaximumProcessorCount != NULL) {
11396 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11397 }
11398 else {
11399 SYSTEM_INFO sysinfo;
11400 GetSystemInfo(&sysinfo);
11401 ncpu = sysinfo.dwNumberOfProcessors;
11402 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011403#elif defined(__hpux)
11404 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11405#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11406 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011407#elif defined(__DragonFly__) || \
11408 defined(__OpenBSD__) || \
11409 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011410 defined(__NetBSD__) || \
11411 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011412 int mib[2];
11413 size_t len = sizeof(ncpu);
11414 mib[0] = CTL_HW;
11415 mib[1] = HW_NCPU;
11416 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11417 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011418#endif
11419 if (ncpu >= 1)
11420 return PyLong_FromLong(ncpu);
11421 else
11422 Py_RETURN_NONE;
11423}
11424
Victor Stinnerdaf45552013-08-28 00:53:59 +020011425
Larry Hastings2f936352014-08-05 14:04:04 +100011426/*[clinic input]
11427os.get_inheritable -> bool
11428
11429 fd: int
11430 /
11431
11432Get the close-on-exe flag of the specified file descriptor.
11433[clinic start generated code]*/
11434
Larry Hastings2f936352014-08-05 14:04:04 +100011435static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011436os_get_inheritable_impl(PyObject *module, int fd)
11437/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011438{
Steve Dower8fc89802015-04-12 00:26:27 -040011439 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011440 _Py_BEGIN_SUPPRESS_IPH
11441 return_value = _Py_get_inheritable(fd);
11442 _Py_END_SUPPRESS_IPH
11443 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011444}
11445
11446
11447/*[clinic input]
11448os.set_inheritable
11449 fd: int
11450 inheritable: int
11451 /
11452
11453Set the inheritable flag of the specified file descriptor.
11454[clinic start generated code]*/
11455
Larry Hastings2f936352014-08-05 14:04:04 +100011456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011457os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11458/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011459{
Steve Dower8fc89802015-04-12 00:26:27 -040011460 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011461
Steve Dower8fc89802015-04-12 00:26:27 -040011462 _Py_BEGIN_SUPPRESS_IPH
11463 result = _Py_set_inheritable(fd, inheritable, NULL);
11464 _Py_END_SUPPRESS_IPH
11465 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011466 return NULL;
11467 Py_RETURN_NONE;
11468}
11469
11470
11471#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011472/*[clinic input]
11473os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011474 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011475 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011476
Larry Hastings2f936352014-08-05 14:04:04 +100011477Get the close-on-exe flag of the specified file descriptor.
11478[clinic start generated code]*/
11479
Larry Hastings2f936352014-08-05 14:04:04 +100011480static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011481os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011482/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011483{
11484 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011485
11486 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11487 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011488 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011489 }
11490
Larry Hastings2f936352014-08-05 14:04:04 +100011491 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011492}
11493
Victor Stinnerdaf45552013-08-28 00:53:59 +020011494
Larry Hastings2f936352014-08-05 14:04:04 +100011495/*[clinic input]
11496os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011497 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011498 inheritable: bool
11499 /
11500
11501Set the inheritable flag of the specified handle.
11502[clinic start generated code]*/
11503
Larry Hastings2f936352014-08-05 14:04:04 +100011504static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011505os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011506 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011507/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011508{
11509 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011510 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11511 PyErr_SetFromWindowsErr(0);
11512 return NULL;
11513 }
11514 Py_RETURN_NONE;
11515}
Larry Hastings2f936352014-08-05 14:04:04 +100011516#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011517
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011518#ifndef MS_WINDOWS
11519PyDoc_STRVAR(get_blocking__doc__,
11520 "get_blocking(fd) -> bool\n" \
11521 "\n" \
11522 "Get the blocking mode of the file descriptor:\n" \
11523 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11524
11525static PyObject*
11526posix_get_blocking(PyObject *self, PyObject *args)
11527{
11528 int fd;
11529 int blocking;
11530
11531 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11532 return NULL;
11533
Steve Dower8fc89802015-04-12 00:26:27 -040011534 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011535 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011536 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011537 if (blocking < 0)
11538 return NULL;
11539 return PyBool_FromLong(blocking);
11540}
11541
11542PyDoc_STRVAR(set_blocking__doc__,
11543 "set_blocking(fd, blocking)\n" \
11544 "\n" \
11545 "Set the blocking mode of the specified file descriptor.\n" \
11546 "Set the O_NONBLOCK flag if blocking is False,\n" \
11547 "clear the O_NONBLOCK flag otherwise.");
11548
11549static PyObject*
11550posix_set_blocking(PyObject *self, PyObject *args)
11551{
Steve Dower8fc89802015-04-12 00:26:27 -040011552 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011553
11554 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11555 return NULL;
11556
Steve Dower8fc89802015-04-12 00:26:27 -040011557 _Py_BEGIN_SUPPRESS_IPH
11558 result = _Py_set_blocking(fd, blocking);
11559 _Py_END_SUPPRESS_IPH
11560 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011561 return NULL;
11562 Py_RETURN_NONE;
11563}
11564#endif /* !MS_WINDOWS */
11565
11566
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011567/*[clinic input]
11568class os.DirEntry "DirEntry *" "&DirEntryType"
11569[clinic start generated code]*/
11570/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011571
11572typedef struct {
11573 PyObject_HEAD
11574 PyObject *name;
11575 PyObject *path;
11576 PyObject *stat;
11577 PyObject *lstat;
11578#ifdef MS_WINDOWS
11579 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011580 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011581 int got_file_index;
11582#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011583#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011584 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011585#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011586 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011587 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011588#endif
11589} DirEntry;
11590
11591static void
11592DirEntry_dealloc(DirEntry *entry)
11593{
11594 Py_XDECREF(entry->name);
11595 Py_XDECREF(entry->path);
11596 Py_XDECREF(entry->stat);
11597 Py_XDECREF(entry->lstat);
11598 Py_TYPE(entry)->tp_free((PyObject *)entry);
11599}
11600
11601/* Forward reference */
11602static int
11603DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11604
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011605/*[clinic input]
11606os.DirEntry.is_symlink -> bool
11607
11608Return True if the entry is a symbolic link; cached per entry.
11609[clinic start generated code]*/
11610
Victor Stinner6036e442015-03-08 01:58:04 +010011611static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011612os_DirEntry_is_symlink_impl(DirEntry *self)
11613/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011614{
11615#ifdef MS_WINDOWS
11616 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011617#elif defined(HAVE_DIRENT_D_TYPE)
11618 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011619 if (self->d_type != DT_UNKNOWN)
11620 return self->d_type == DT_LNK;
11621 else
11622 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011623#else
11624 /* POSIX without d_type */
11625 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011626#endif
11627}
11628
11629static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011630DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11631{
11632 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011633 STRUCT_STAT st;
11634 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011635
11636#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011637 if (!PyUnicode_FSDecoder(self->path, &ub))
11638 return NULL;
11639 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011640#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011641 if (!PyUnicode_FSConverter(self->path, &ub))
11642 return NULL;
11643 const char *path = PyBytes_AS_STRING(ub);
11644 if (self->dir_fd != DEFAULT_DIR_FD) {
11645#ifdef HAVE_FSTATAT
11646 result = fstatat(self->dir_fd, path, &st,
11647 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11648#else
11649 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11650 return NULL;
11651#endif /* HAVE_FSTATAT */
11652 }
11653 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011654#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011655 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011656 if (follow_symlinks)
11657 result = STAT(path, &st);
11658 else
11659 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011660 }
11661 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011662
11663 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011664 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011665
11666 return _pystat_fromstructstat(&st);
11667}
11668
11669static PyObject *
11670DirEntry_get_lstat(DirEntry *self)
11671{
11672 if (!self->lstat) {
11673#ifdef MS_WINDOWS
11674 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11675#else /* POSIX */
11676 self->lstat = DirEntry_fetch_stat(self, 0);
11677#endif
11678 }
11679 Py_XINCREF(self->lstat);
11680 return self->lstat;
11681}
11682
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011683/*[clinic input]
11684os.DirEntry.stat
11685 *
11686 follow_symlinks: bool = True
11687
11688Return stat_result object for the entry; cached per entry.
11689[clinic start generated code]*/
11690
Victor Stinner6036e442015-03-08 01:58:04 +010011691static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011692os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11693/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011694{
11695 if (!follow_symlinks)
11696 return DirEntry_get_lstat(self);
11697
11698 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011699 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011700 if (result == -1)
11701 return NULL;
11702 else if (result)
11703 self->stat = DirEntry_fetch_stat(self, 1);
11704 else
11705 self->stat = DirEntry_get_lstat(self);
11706 }
11707
11708 Py_XINCREF(self->stat);
11709 return self->stat;
11710}
11711
Victor Stinner6036e442015-03-08 01:58:04 +010011712/* Set exception and return -1 on error, 0 for False, 1 for True */
11713static int
11714DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11715{
11716 PyObject *stat = NULL;
11717 PyObject *st_mode = NULL;
11718 long mode;
11719 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011720#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011721 int is_symlink;
11722 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011723#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011724#ifdef MS_WINDOWS
11725 unsigned long dir_bits;
11726#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011727 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011728
11729#ifdef MS_WINDOWS
11730 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11731 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011732#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011733 is_symlink = self->d_type == DT_LNK;
11734 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11735#endif
11736
Victor Stinner35a97c02015-03-08 02:59:09 +010011737#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011738 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011739#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011740 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011741 if (!stat) {
11742 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11743 /* If file doesn't exist (anymore), then return False
11744 (i.e., say it's not a file/directory) */
11745 PyErr_Clear();
11746 return 0;
11747 }
11748 goto error;
11749 }
11750 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11751 if (!st_mode)
11752 goto error;
11753
11754 mode = PyLong_AsLong(st_mode);
11755 if (mode == -1 && PyErr_Occurred())
11756 goto error;
11757 Py_CLEAR(st_mode);
11758 Py_CLEAR(stat);
11759 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011760#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011761 }
11762 else if (is_symlink) {
11763 assert(mode_bits != S_IFLNK);
11764 result = 0;
11765 }
11766 else {
11767 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11768#ifdef MS_WINDOWS
11769 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11770 if (mode_bits == S_IFDIR)
11771 result = dir_bits != 0;
11772 else
11773 result = dir_bits == 0;
11774#else /* POSIX */
11775 if (mode_bits == S_IFDIR)
11776 result = self->d_type == DT_DIR;
11777 else
11778 result = self->d_type == DT_REG;
11779#endif
11780 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011781#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011782
11783 return result;
11784
11785error:
11786 Py_XDECREF(st_mode);
11787 Py_XDECREF(stat);
11788 return -1;
11789}
11790
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011791/*[clinic input]
11792os.DirEntry.is_dir -> bool
11793 *
11794 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011795
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011796Return True if the entry is a directory; cached per entry.
11797[clinic start generated code]*/
11798
11799static int
11800os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11801/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11802{
11803 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011804}
11805
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011806/*[clinic input]
11807os.DirEntry.is_file -> bool
11808 *
11809 follow_symlinks: bool = True
11810
11811Return True if the entry is a file; cached per entry.
11812[clinic start generated code]*/
11813
11814static int
11815os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11816/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011817{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011818 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011819}
11820
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011821/*[clinic input]
11822os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011823
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011824Return inode of the entry; cached per entry.
11825[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011826
11827static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011828os_DirEntry_inode_impl(DirEntry *self)
11829/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011830{
11831#ifdef MS_WINDOWS
11832 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011833 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011834 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011835 STRUCT_STAT stat;
11836 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011837
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011838 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011839 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011840 path = PyUnicode_AsUnicode(unicode);
11841 result = LSTAT(path, &stat);
11842 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011843
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011844 if (result != 0)
11845 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011846
11847 self->win32_file_index = stat.st_ino;
11848 self->got_file_index = 1;
11849 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011850 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11851 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011852#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011853 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11854 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011855#endif
11856}
11857
11858static PyObject *
11859DirEntry_repr(DirEntry *self)
11860{
11861 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11862}
11863
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011864/*[clinic input]
11865os.DirEntry.__fspath__
11866
11867Returns the path for the entry.
11868[clinic start generated code]*/
11869
Brett Cannon96881cd2016-06-10 14:37:21 -070011870static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011871os_DirEntry___fspath___impl(DirEntry *self)
11872/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011873{
11874 Py_INCREF(self->path);
11875 return self->path;
11876}
11877
Victor Stinner6036e442015-03-08 01:58:04 +010011878static PyMemberDef DirEntry_members[] = {
11879 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11880 "the entry's base filename, relative to scandir() \"path\" argument"},
11881 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11882 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11883 {NULL}
11884};
11885
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011886#include "clinic/posixmodule.c.h"
11887
Victor Stinner6036e442015-03-08 01:58:04 +010011888static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011889 OS_DIRENTRY_IS_DIR_METHODDEF
11890 OS_DIRENTRY_IS_FILE_METHODDEF
11891 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11892 OS_DIRENTRY_STAT_METHODDEF
11893 OS_DIRENTRY_INODE_METHODDEF
11894 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011895 {NULL}
11896};
11897
Benjamin Peterson5646de42015-04-12 17:56:34 -040011898static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011899 PyVarObject_HEAD_INIT(NULL, 0)
11900 MODNAME ".DirEntry", /* tp_name */
11901 sizeof(DirEntry), /* tp_basicsize */
11902 0, /* tp_itemsize */
11903 /* methods */
11904 (destructor)DirEntry_dealloc, /* tp_dealloc */
11905 0, /* tp_print */
11906 0, /* tp_getattr */
11907 0, /* tp_setattr */
11908 0, /* tp_compare */
11909 (reprfunc)DirEntry_repr, /* tp_repr */
11910 0, /* tp_as_number */
11911 0, /* tp_as_sequence */
11912 0, /* tp_as_mapping */
11913 0, /* tp_hash */
11914 0, /* tp_call */
11915 0, /* tp_str */
11916 0, /* tp_getattro */
11917 0, /* tp_setattro */
11918 0, /* tp_as_buffer */
11919 Py_TPFLAGS_DEFAULT, /* tp_flags */
11920 0, /* tp_doc */
11921 0, /* tp_traverse */
11922 0, /* tp_clear */
11923 0, /* tp_richcompare */
11924 0, /* tp_weaklistoffset */
11925 0, /* tp_iter */
11926 0, /* tp_iternext */
11927 DirEntry_methods, /* tp_methods */
11928 DirEntry_members, /* tp_members */
11929};
11930
11931#ifdef MS_WINDOWS
11932
11933static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011934join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011935{
11936 Py_ssize_t path_len;
11937 Py_ssize_t size;
11938 wchar_t *result;
11939 wchar_t ch;
11940
11941 if (!path_wide) { /* Default arg: "." */
11942 path_wide = L".";
11943 path_len = 1;
11944 }
11945 else {
11946 path_len = wcslen(path_wide);
11947 }
11948
11949 /* The +1's are for the path separator and the NUL */
11950 size = path_len + 1 + wcslen(filename) + 1;
11951 result = PyMem_New(wchar_t, size);
11952 if (!result) {
11953 PyErr_NoMemory();
11954 return NULL;
11955 }
11956 wcscpy(result, path_wide);
11957 if (path_len > 0) {
11958 ch = result[path_len - 1];
11959 if (ch != SEP && ch != ALTSEP && ch != L':')
11960 result[path_len++] = SEP;
11961 wcscpy(result + path_len, filename);
11962 }
11963 return result;
11964}
11965
11966static PyObject *
11967DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11968{
11969 DirEntry *entry;
11970 BY_HANDLE_FILE_INFORMATION file_info;
11971 ULONG reparse_tag;
11972 wchar_t *joined_path;
11973
11974 entry = PyObject_New(DirEntry, &DirEntryType);
11975 if (!entry)
11976 return NULL;
11977 entry->name = NULL;
11978 entry->path = NULL;
11979 entry->stat = NULL;
11980 entry->lstat = NULL;
11981 entry->got_file_index = 0;
11982
11983 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11984 if (!entry->name)
11985 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011986 if (path->narrow) {
11987 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11988 if (!entry->name)
11989 goto error;
11990 }
Victor Stinner6036e442015-03-08 01:58:04 +010011991
11992 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11993 if (!joined_path)
11994 goto error;
11995
11996 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11997 PyMem_Free(joined_path);
11998 if (!entry->path)
11999 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012000 if (path->narrow) {
12001 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12002 if (!entry->path)
12003 goto error;
12004 }
Victor Stinner6036e442015-03-08 01:58:04 +010012005
Steve Dowercc16be82016-09-08 10:35:16 -070012006 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012007 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12008
12009 return (PyObject *)entry;
12010
12011error:
12012 Py_DECREF(entry);
12013 return NULL;
12014}
12015
12016#else /* POSIX */
12017
12018static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012019join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012020{
12021 Py_ssize_t path_len;
12022 Py_ssize_t size;
12023 char *result;
12024
12025 if (!path_narrow) { /* Default arg: "." */
12026 path_narrow = ".";
12027 path_len = 1;
12028 }
12029 else {
12030 path_len = strlen(path_narrow);
12031 }
12032
12033 if (filename_len == -1)
12034 filename_len = strlen(filename);
12035
12036 /* The +1's are for the path separator and the NUL */
12037 size = path_len + 1 + filename_len + 1;
12038 result = PyMem_New(char, size);
12039 if (!result) {
12040 PyErr_NoMemory();
12041 return NULL;
12042 }
12043 strcpy(result, path_narrow);
12044 if (path_len > 0 && result[path_len - 1] != '/')
12045 result[path_len++] = '/';
12046 strcpy(result + path_len, filename);
12047 return result;
12048}
12049
12050static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012051DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012052 ino_t d_ino
12053#ifdef HAVE_DIRENT_D_TYPE
12054 , unsigned char d_type
12055#endif
12056 )
Victor Stinner6036e442015-03-08 01:58:04 +010012057{
12058 DirEntry *entry;
12059 char *joined_path;
12060
12061 entry = PyObject_New(DirEntry, &DirEntryType);
12062 if (!entry)
12063 return NULL;
12064 entry->name = NULL;
12065 entry->path = NULL;
12066 entry->stat = NULL;
12067 entry->lstat = NULL;
12068
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012069 if (path->fd != -1) {
12070 entry->dir_fd = path->fd;
12071 joined_path = NULL;
12072 }
12073 else {
12074 entry->dir_fd = DEFAULT_DIR_FD;
12075 joined_path = join_path_filename(path->narrow, name, name_len);
12076 if (!joined_path)
12077 goto error;
12078 }
Victor Stinner6036e442015-03-08 01:58:04 +010012079
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012080 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012081 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012082 if (joined_path)
12083 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012084 }
12085 else {
12086 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012087 if (joined_path)
12088 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012089 }
12090 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012091 if (!entry->name)
12092 goto error;
12093
12094 if (path->fd != -1) {
12095 entry->path = entry->name;
12096 Py_INCREF(entry->path);
12097 }
12098 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012099 goto error;
12100
Victor Stinner35a97c02015-03-08 02:59:09 +010012101#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012102 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012103#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012104 entry->d_ino = d_ino;
12105
12106 return (PyObject *)entry;
12107
12108error:
12109 Py_XDECREF(entry);
12110 return NULL;
12111}
12112
12113#endif
12114
12115
12116typedef struct {
12117 PyObject_HEAD
12118 path_t path;
12119#ifdef MS_WINDOWS
12120 HANDLE handle;
12121 WIN32_FIND_DATAW file_data;
12122 int first_time;
12123#else /* POSIX */
12124 DIR *dirp;
12125#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012126#ifdef HAVE_FDOPENDIR
12127 int fd;
12128#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012129} ScandirIterator;
12130
12131#ifdef MS_WINDOWS
12132
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012133static int
12134ScandirIterator_is_closed(ScandirIterator *iterator)
12135{
12136 return iterator->handle == INVALID_HANDLE_VALUE;
12137}
12138
Victor Stinner6036e442015-03-08 01:58:04 +010012139static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012140ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012141{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012142 HANDLE handle = iterator->handle;
12143
12144 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012145 return;
12146
Victor Stinner6036e442015-03-08 01:58:04 +010012147 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012148 Py_BEGIN_ALLOW_THREADS
12149 FindClose(handle);
12150 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012151}
12152
12153static PyObject *
12154ScandirIterator_iternext(ScandirIterator *iterator)
12155{
12156 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12157 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012158 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012159
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012160 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012161 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012162 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012163
12164 while (1) {
12165 if (!iterator->first_time) {
12166 Py_BEGIN_ALLOW_THREADS
12167 success = FindNextFileW(iterator->handle, file_data);
12168 Py_END_ALLOW_THREADS
12169 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012170 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012171 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012172 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012173 break;
12174 }
12175 }
12176 iterator->first_time = 0;
12177
12178 /* Skip over . and .. */
12179 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012180 wcscmp(file_data->cFileName, L"..") != 0) {
12181 entry = DirEntry_from_find_data(&iterator->path, file_data);
12182 if (!entry)
12183 break;
12184 return entry;
12185 }
Victor Stinner6036e442015-03-08 01:58:04 +010012186
12187 /* Loop till we get a non-dot directory or finish iterating */
12188 }
12189
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012190 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012191 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012192 return NULL;
12193}
12194
12195#else /* POSIX */
12196
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012197static int
12198ScandirIterator_is_closed(ScandirIterator *iterator)
12199{
12200 return !iterator->dirp;
12201}
12202
Victor Stinner6036e442015-03-08 01:58:04 +010012203static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012204ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012205{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012206 DIR *dirp = iterator->dirp;
12207
12208 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012209 return;
12210
Victor Stinner6036e442015-03-08 01:58:04 +010012211 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012212 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012213#ifdef HAVE_FDOPENDIR
12214 if (iterator->path.fd != -1)
12215 rewinddir(dirp);
12216#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012217 closedir(dirp);
12218 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012219 return;
12220}
12221
12222static PyObject *
12223ScandirIterator_iternext(ScandirIterator *iterator)
12224{
12225 struct dirent *direntp;
12226 Py_ssize_t name_len;
12227 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012228 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012229
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012230 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012231 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012232 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012233
12234 while (1) {
12235 errno = 0;
12236 Py_BEGIN_ALLOW_THREADS
12237 direntp = readdir(iterator->dirp);
12238 Py_END_ALLOW_THREADS
12239
12240 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012241 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012242 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012243 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012244 break;
12245 }
12246
12247 /* Skip over . and .. */
12248 name_len = NAMLEN(direntp);
12249 is_dot = direntp->d_name[0] == '.' &&
12250 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12251 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012252 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012253 name_len, direntp->d_ino
12254#ifdef HAVE_DIRENT_D_TYPE
12255 , direntp->d_type
12256#endif
12257 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012258 if (!entry)
12259 break;
12260 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012261 }
12262
12263 /* Loop till we get a non-dot directory or finish iterating */
12264 }
12265
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012266 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012267 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012268 return NULL;
12269}
12270
12271#endif
12272
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012273static PyObject *
12274ScandirIterator_close(ScandirIterator *self, PyObject *args)
12275{
12276 ScandirIterator_closedir(self);
12277 Py_RETURN_NONE;
12278}
12279
12280static PyObject *
12281ScandirIterator_enter(PyObject *self, PyObject *args)
12282{
12283 Py_INCREF(self);
12284 return self;
12285}
12286
12287static PyObject *
12288ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12289{
12290 ScandirIterator_closedir(self);
12291 Py_RETURN_NONE;
12292}
12293
Victor Stinner6036e442015-03-08 01:58:04 +010012294static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012295ScandirIterator_finalize(ScandirIterator *iterator)
12296{
12297 PyObject *error_type, *error_value, *error_traceback;
12298
12299 /* Save the current exception, if any. */
12300 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12301
12302 if (!ScandirIterator_is_closed(iterator)) {
12303 ScandirIterator_closedir(iterator);
12304
12305 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12306 "unclosed scandir iterator %R", iterator)) {
12307 /* Spurious errors can appear at shutdown */
12308 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12309 PyErr_WriteUnraisable((PyObject *) iterator);
12310 }
12311 }
12312 }
12313
Victor Stinner7bfa4092016-03-23 00:43:54 +010012314 path_cleanup(&iterator->path);
12315
12316 /* Restore the saved exception. */
12317 PyErr_Restore(error_type, error_value, error_traceback);
12318}
12319
12320static void
Victor Stinner6036e442015-03-08 01:58:04 +010012321ScandirIterator_dealloc(ScandirIterator *iterator)
12322{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012323 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12324 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012325
Victor Stinner6036e442015-03-08 01:58:04 +010012326 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12327}
12328
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012329static PyMethodDef ScandirIterator_methods[] = {
12330 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12331 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12332 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12333 {NULL}
12334};
12335
Benjamin Peterson5646de42015-04-12 17:56:34 -040012336static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012337 PyVarObject_HEAD_INIT(NULL, 0)
12338 MODNAME ".ScandirIterator", /* tp_name */
12339 sizeof(ScandirIterator), /* tp_basicsize */
12340 0, /* tp_itemsize */
12341 /* methods */
12342 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12343 0, /* tp_print */
12344 0, /* tp_getattr */
12345 0, /* tp_setattr */
12346 0, /* tp_compare */
12347 0, /* tp_repr */
12348 0, /* tp_as_number */
12349 0, /* tp_as_sequence */
12350 0, /* tp_as_mapping */
12351 0, /* tp_hash */
12352 0, /* tp_call */
12353 0, /* tp_str */
12354 0, /* tp_getattro */
12355 0, /* tp_setattro */
12356 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012357 Py_TPFLAGS_DEFAULT
12358 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012359 0, /* tp_doc */
12360 0, /* tp_traverse */
12361 0, /* tp_clear */
12362 0, /* tp_richcompare */
12363 0, /* tp_weaklistoffset */
12364 PyObject_SelfIter, /* tp_iter */
12365 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012366 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012367 0, /* tp_members */
12368 0, /* tp_getset */
12369 0, /* tp_base */
12370 0, /* tp_dict */
12371 0, /* tp_descr_get */
12372 0, /* tp_descr_set */
12373 0, /* tp_dictoffset */
12374 0, /* tp_init */
12375 0, /* tp_alloc */
12376 0, /* tp_new */
12377 0, /* tp_free */
12378 0, /* tp_is_gc */
12379 0, /* tp_bases */
12380 0, /* tp_mro */
12381 0, /* tp_cache */
12382 0, /* tp_subclasses */
12383 0, /* tp_weaklist */
12384 0, /* tp_del */
12385 0, /* tp_version_tag */
12386 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012387};
12388
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012389/*[clinic input]
12390os.scandir
12391
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012392 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012393
12394Return an iterator of DirEntry objects for given path.
12395
BNMetrics08026b12018-11-02 17:56:25 +000012396path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012397is bytes, the names of yielded DirEntry objects will also be bytes; in
12398all other circumstances they will be str.
12399
12400If path is None, uses the path='.'.
12401[clinic start generated code]*/
12402
Victor Stinner6036e442015-03-08 01:58:04 +010012403static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012404os_scandir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +000012405/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012406{
12407 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012408#ifdef MS_WINDOWS
12409 wchar_t *path_strW;
12410#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012411 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012412#ifdef HAVE_FDOPENDIR
12413 int fd = -1;
12414#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012415#endif
12416
12417 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12418 if (!iterator)
12419 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012420
12421#ifdef MS_WINDOWS
12422 iterator->handle = INVALID_HANDLE_VALUE;
12423#else
12424 iterator->dirp = NULL;
12425#endif
12426
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012427 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012428 /* Move the ownership to iterator->path */
12429 path->object = NULL;
12430 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012431
12432#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012433 iterator->first_time = 1;
12434
12435 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12436 if (!path_strW)
12437 goto error;
12438
12439 Py_BEGIN_ALLOW_THREADS
12440 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12441 Py_END_ALLOW_THREADS
12442
12443 PyMem_Free(path_strW);
12444
12445 if (iterator->handle == INVALID_HANDLE_VALUE) {
12446 path_error(&iterator->path);
12447 goto error;
12448 }
12449#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012450 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012451#ifdef HAVE_FDOPENDIR
12452 if (path->fd != -1) {
12453 /* closedir() closes the FD, so we duplicate it */
12454 fd = _Py_dup(path->fd);
12455 if (fd == -1)
12456 goto error;
12457
12458 Py_BEGIN_ALLOW_THREADS
12459 iterator->dirp = fdopendir(fd);
12460 Py_END_ALLOW_THREADS
12461 }
12462 else
12463#endif
12464 {
12465 if (iterator->path.narrow)
12466 path_str = iterator->path.narrow;
12467 else
12468 path_str = ".";
12469
12470 Py_BEGIN_ALLOW_THREADS
12471 iterator->dirp = opendir(path_str);
12472 Py_END_ALLOW_THREADS
12473 }
Victor Stinner6036e442015-03-08 01:58:04 +010012474
12475 if (!iterator->dirp) {
12476 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012477#ifdef HAVE_FDOPENDIR
12478 if (fd != -1) {
12479 Py_BEGIN_ALLOW_THREADS
12480 close(fd);
12481 Py_END_ALLOW_THREADS
12482 }
12483#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012484 goto error;
12485 }
12486#endif
12487
12488 return (PyObject *)iterator;
12489
12490error:
12491 Py_DECREF(iterator);
12492 return NULL;
12493}
12494
Ethan Furman410ef8e2016-06-04 12:06:26 -070012495/*
12496 Return the file system path representation of the object.
12497
12498 If the object is str or bytes, then allow it to pass through with
12499 an incremented refcount. If the object defines __fspath__(), then
12500 return the result of that method. All other types raise a TypeError.
12501*/
12502PyObject *
12503PyOS_FSPath(PyObject *path)
12504{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012505 /* For error message reasons, this function is manually inlined in
12506 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012507 _Py_IDENTIFIER(__fspath__);
12508 PyObject *func = NULL;
12509 PyObject *path_repr = NULL;
12510
12511 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12512 Py_INCREF(path);
12513 return path;
12514 }
12515
12516 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12517 if (NULL == func) {
12518 return PyErr_Format(PyExc_TypeError,
12519 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012520 "not %.200s",
12521 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012522 }
12523
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012524 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012525 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012526 if (NULL == path_repr) {
12527 return NULL;
12528 }
12529
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012530 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12531 PyErr_Format(PyExc_TypeError,
12532 "expected %.200s.__fspath__() to return str or bytes, "
12533 "not %.200s", Py_TYPE(path)->tp_name,
12534 Py_TYPE(path_repr)->tp_name);
12535 Py_DECREF(path_repr);
12536 return NULL;
12537 }
12538
Ethan Furman410ef8e2016-06-04 12:06:26 -070012539 return path_repr;
12540}
12541
12542/*[clinic input]
12543os.fspath
12544
12545 path: object
12546
12547Return the file system path representation of the object.
12548
Brett Cannonb4f43e92016-06-09 14:32:08 -070012549If the object is str or bytes, then allow it to pass through as-is. If the
12550object defines __fspath__(), then return the result of that method. All other
12551types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012552[clinic start generated code]*/
12553
12554static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012555os_fspath_impl(PyObject *module, PyObject *path)
12556/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012557{
12558 return PyOS_FSPath(path);
12559}
Victor Stinner6036e442015-03-08 01:58:04 +010012560
Victor Stinner9b1f4742016-09-06 16:18:52 -070012561#ifdef HAVE_GETRANDOM_SYSCALL
12562/*[clinic input]
12563os.getrandom
12564
12565 size: Py_ssize_t
12566 flags: int=0
12567
12568Obtain a series of random bytes.
12569[clinic start generated code]*/
12570
12571static PyObject *
12572os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12573/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12574{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012575 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012576 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012577
12578 if (size < 0) {
12579 errno = EINVAL;
12580 return posix_error();
12581 }
12582
Victor Stinnerec2319c2016-09-20 23:00:59 +020012583 bytes = PyBytes_FromStringAndSize(NULL, size);
12584 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012585 PyErr_NoMemory();
12586 return NULL;
12587 }
12588
12589 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012590 n = syscall(SYS_getrandom,
12591 PyBytes_AS_STRING(bytes),
12592 PyBytes_GET_SIZE(bytes),
12593 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012594 if (n < 0 && errno == EINTR) {
12595 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012596 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012597 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012598
12599 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012600 continue;
12601 }
12602 break;
12603 }
12604
12605 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012606 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012607 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012608 }
12609
Victor Stinnerec2319c2016-09-20 23:00:59 +020012610 if (n != size) {
12611 _PyBytes_Resize(&bytes, n);
12612 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012613
12614 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012615
12616error:
12617 Py_DECREF(bytes);
12618 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012619}
12620#endif /* HAVE_GETRANDOM_SYSCALL */
12621
Larry Hastings31826802013-10-19 00:09:25 -070012622
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012623static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012624
12625 OS_STAT_METHODDEF
12626 OS_ACCESS_METHODDEF
12627 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012628 OS_CHDIR_METHODDEF
12629 OS_CHFLAGS_METHODDEF
12630 OS_CHMOD_METHODDEF
12631 OS_FCHMOD_METHODDEF
12632 OS_LCHMOD_METHODDEF
12633 OS_CHOWN_METHODDEF
12634 OS_FCHOWN_METHODDEF
12635 OS_LCHOWN_METHODDEF
12636 OS_LCHFLAGS_METHODDEF
12637 OS_CHROOT_METHODDEF
12638 OS_CTERMID_METHODDEF
12639 OS_GETCWD_METHODDEF
12640 OS_GETCWDB_METHODDEF
12641 OS_LINK_METHODDEF
12642 OS_LISTDIR_METHODDEF
12643 OS_LSTAT_METHODDEF
12644 OS_MKDIR_METHODDEF
12645 OS_NICE_METHODDEF
12646 OS_GETPRIORITY_METHODDEF
12647 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012648#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012649 {"readlink", (PyCFunction)posix_readlink,
12650 METH_VARARGS | METH_KEYWORDS,
12651 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012652#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012653#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012654 {"readlink", (PyCFunction)win_readlink,
12655 METH_VARARGS | METH_KEYWORDS,
12656 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012657#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012658 OS_RENAME_METHODDEF
12659 OS_REPLACE_METHODDEF
12660 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012661 OS_SYMLINK_METHODDEF
12662 OS_SYSTEM_METHODDEF
12663 OS_UMASK_METHODDEF
12664 OS_UNAME_METHODDEF
12665 OS_UNLINK_METHODDEF
12666 OS_REMOVE_METHODDEF
12667 OS_UTIME_METHODDEF
12668 OS_TIMES_METHODDEF
12669 OS__EXIT_METHODDEF
12670 OS_EXECV_METHODDEF
12671 OS_EXECVE_METHODDEF
12672 OS_SPAWNV_METHODDEF
12673 OS_SPAWNVE_METHODDEF
12674 OS_FORK1_METHODDEF
12675 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012676 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012677 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12678 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12679 OS_SCHED_GETPARAM_METHODDEF
12680 OS_SCHED_GETSCHEDULER_METHODDEF
12681 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12682 OS_SCHED_SETPARAM_METHODDEF
12683 OS_SCHED_SETSCHEDULER_METHODDEF
12684 OS_SCHED_YIELD_METHODDEF
12685 OS_SCHED_SETAFFINITY_METHODDEF
12686 OS_SCHED_GETAFFINITY_METHODDEF
12687 OS_OPENPTY_METHODDEF
12688 OS_FORKPTY_METHODDEF
12689 OS_GETEGID_METHODDEF
12690 OS_GETEUID_METHODDEF
12691 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012692#ifdef HAVE_GETGROUPLIST
12693 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12694#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012695 OS_GETGROUPS_METHODDEF
12696 OS_GETPID_METHODDEF
12697 OS_GETPGRP_METHODDEF
12698 OS_GETPPID_METHODDEF
12699 OS_GETUID_METHODDEF
12700 OS_GETLOGIN_METHODDEF
12701 OS_KILL_METHODDEF
12702 OS_KILLPG_METHODDEF
12703 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012704#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012705 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012706#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012707 OS_SETUID_METHODDEF
12708 OS_SETEUID_METHODDEF
12709 OS_SETREUID_METHODDEF
12710 OS_SETGID_METHODDEF
12711 OS_SETEGID_METHODDEF
12712 OS_SETREGID_METHODDEF
12713 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012714#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012715 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012716#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012717 OS_GETPGID_METHODDEF
12718 OS_SETPGRP_METHODDEF
12719 OS_WAIT_METHODDEF
12720 OS_WAIT3_METHODDEF
12721 OS_WAIT4_METHODDEF
12722 OS_WAITID_METHODDEF
12723 OS_WAITPID_METHODDEF
12724 OS_GETSID_METHODDEF
12725 OS_SETSID_METHODDEF
12726 OS_SETPGID_METHODDEF
12727 OS_TCGETPGRP_METHODDEF
12728 OS_TCSETPGRP_METHODDEF
12729 OS_OPEN_METHODDEF
12730 OS_CLOSE_METHODDEF
12731 OS_CLOSERANGE_METHODDEF
12732 OS_DEVICE_ENCODING_METHODDEF
12733 OS_DUP_METHODDEF
12734 OS_DUP2_METHODDEF
12735 OS_LOCKF_METHODDEF
12736 OS_LSEEK_METHODDEF
12737 OS_READ_METHODDEF
12738 OS_READV_METHODDEF
12739 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012740 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012741 OS_WRITE_METHODDEF
12742 OS_WRITEV_METHODDEF
12743 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012744 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012745#ifdef HAVE_SENDFILE
12746 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12747 posix_sendfile__doc__},
12748#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012749 OS_FSTAT_METHODDEF
12750 OS_ISATTY_METHODDEF
12751 OS_PIPE_METHODDEF
12752 OS_PIPE2_METHODDEF
12753 OS_MKFIFO_METHODDEF
12754 OS_MKNOD_METHODDEF
12755 OS_MAJOR_METHODDEF
12756 OS_MINOR_METHODDEF
12757 OS_MAKEDEV_METHODDEF
12758 OS_FTRUNCATE_METHODDEF
12759 OS_TRUNCATE_METHODDEF
12760 OS_POSIX_FALLOCATE_METHODDEF
12761 OS_POSIX_FADVISE_METHODDEF
12762 OS_PUTENV_METHODDEF
12763 OS_UNSETENV_METHODDEF
12764 OS_STRERROR_METHODDEF
12765 OS_FCHDIR_METHODDEF
12766 OS_FSYNC_METHODDEF
12767 OS_SYNC_METHODDEF
12768 OS_FDATASYNC_METHODDEF
12769 OS_WCOREDUMP_METHODDEF
12770 OS_WIFCONTINUED_METHODDEF
12771 OS_WIFSTOPPED_METHODDEF
12772 OS_WIFSIGNALED_METHODDEF
12773 OS_WIFEXITED_METHODDEF
12774 OS_WEXITSTATUS_METHODDEF
12775 OS_WTERMSIG_METHODDEF
12776 OS_WSTOPSIG_METHODDEF
12777 OS_FSTATVFS_METHODDEF
12778 OS_STATVFS_METHODDEF
12779 OS_CONFSTR_METHODDEF
12780 OS_SYSCONF_METHODDEF
12781 OS_FPATHCONF_METHODDEF
12782 OS_PATHCONF_METHODDEF
12783 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012784 OS__GETFULLPATHNAME_METHODDEF
12785 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012786 OS__GETDISKUSAGE_METHODDEF
12787 OS__GETFINALPATHNAME_METHODDEF
12788 OS__GETVOLUMEPATHNAME_METHODDEF
12789 OS_GETLOADAVG_METHODDEF
12790 OS_URANDOM_METHODDEF
12791 OS_SETRESUID_METHODDEF
12792 OS_SETRESGID_METHODDEF
12793 OS_GETRESUID_METHODDEF
12794 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012795
Larry Hastings2f936352014-08-05 14:04:04 +100012796 OS_GETXATTR_METHODDEF
12797 OS_SETXATTR_METHODDEF
12798 OS_REMOVEXATTR_METHODDEF
12799 OS_LISTXATTR_METHODDEF
12800
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012801#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12802 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12803#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012804 OS_CPU_COUNT_METHODDEF
12805 OS_GET_INHERITABLE_METHODDEF
12806 OS_SET_INHERITABLE_METHODDEF
12807 OS_GET_HANDLE_INHERITABLE_METHODDEF
12808 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012809#ifndef MS_WINDOWS
12810 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12811 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12812#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012813 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012814 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012815 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012816 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012817};
12818
12819
Brian Curtin52173d42010-12-02 18:29:18 +000012820#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012821static int
Brian Curtin52173d42010-12-02 18:29:18 +000012822enable_symlink()
12823{
12824 HANDLE tok;
12825 TOKEN_PRIVILEGES tok_priv;
12826 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012827
12828 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012829 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012830
12831 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012832 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012833
12834 tok_priv.PrivilegeCount = 1;
12835 tok_priv.Privileges[0].Luid = luid;
12836 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12837
12838 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12839 sizeof(TOKEN_PRIVILEGES),
12840 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012841 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012842
Brian Curtin3b4499c2010-12-28 14:31:47 +000012843 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12844 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012845}
12846#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12847
Barry Warsaw4a342091996-12-19 23:50:02 +000012848static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012849all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012850{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012851#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012852 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012853#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012854#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012855 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012856#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012857#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012858 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012859#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012860#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012861 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012862#endif
Fred Drakec9680921999-12-13 16:37:25 +000012863#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012864 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012865#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012866#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012867 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012868#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012869#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012870 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012871#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012872#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012873 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012874#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012875#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012876 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012877#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012878#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012880#endif
12881#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012883#endif
12884#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012885 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012886#endif
12887#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012888 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012889#endif
12890#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012891 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012892#endif
12893#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012894 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012895#endif
12896#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012897 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012898#endif
12899#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012900 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012901#endif
12902#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012903 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012904#endif
12905#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012906 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012907#endif
12908#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012909 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012910#endif
12911#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012912 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012913#endif
12914#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012915 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012916#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012917#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012918 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012919#endif
12920#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012922#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012923#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012924 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012925#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012926#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012928#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012929#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012930#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012931 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012932#endif
12933#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012934 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012935#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012936#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012937#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012938 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012939#endif
12940#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012941 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012942#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012943#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012944 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012945#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012946#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012947 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012948#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012949#ifdef O_TMPFILE
12950 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12951#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012952#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012953 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012954#endif
12955#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012956 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012957#endif
12958#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012959 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012960#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012961#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012962 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012963#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012964#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012965 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012966#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012967
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012968
Jesus Cea94363612012-06-22 18:32:07 +020012969#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012970 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012971#endif
12972#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012973 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012974#endif
12975
Tim Peters5aa91602002-01-30 05:46:57 +000012976/* MS Windows */
12977#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012978 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012980#endif
12981#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 /* Optimize for short life (keep in memory). */
12983 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012984 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012985#endif
12986#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012987 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012988 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012989#endif
12990#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012991 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012992 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012993#endif
12994#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012995 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012996 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012997#endif
12998
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012999/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013000#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 /* Send a SIGIO signal whenever input or output
13002 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013003 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013004#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013005#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013006 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013007 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013008#endif
13009#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013010 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013011 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013012#endif
13013#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013014 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013016#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013017#ifdef O_NOLINKS
13018 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013019 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013020#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013021#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013022 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013023 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013024#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013025
Victor Stinner8c62be82010-05-06 00:08:46 +000013026 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013027#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013028 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013029#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013030#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013031 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013032#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013033#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013034 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013035#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013036#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013037 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013038#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013039#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013040 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013041#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013042#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013043 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013044#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013045#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013046 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013047#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013048#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013049 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013050#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013051#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013052 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013053#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013054#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013055 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013056#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013057#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013058 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013059#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013060#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013061 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013062#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013063#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013064 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013065#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013066#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013067 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013068#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013069#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013070 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013071#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013072#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013073 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013074#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013075#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013076 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013077#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013078
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013079 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013080#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013081 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013082#endif /* ST_RDONLY */
13083#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013084 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013085#endif /* ST_NOSUID */
13086
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013087 /* GNU extensions */
13088#ifdef ST_NODEV
13089 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13090#endif /* ST_NODEV */
13091#ifdef ST_NOEXEC
13092 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13093#endif /* ST_NOEXEC */
13094#ifdef ST_SYNCHRONOUS
13095 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13096#endif /* ST_SYNCHRONOUS */
13097#ifdef ST_MANDLOCK
13098 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13099#endif /* ST_MANDLOCK */
13100#ifdef ST_WRITE
13101 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13102#endif /* ST_WRITE */
13103#ifdef ST_APPEND
13104 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13105#endif /* ST_APPEND */
13106#ifdef ST_NOATIME
13107 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13108#endif /* ST_NOATIME */
13109#ifdef ST_NODIRATIME
13110 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13111#endif /* ST_NODIRATIME */
13112#ifdef ST_RELATIME
13113 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13114#endif /* ST_RELATIME */
13115
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013116 /* FreeBSD sendfile() constants */
13117#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013118 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013119#endif
13120#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013121 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013122#endif
13123#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013124 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013125#endif
13126
Ross Lagerwall7807c352011-03-17 20:20:30 +020013127 /* constants for posix_fadvise */
13128#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013129 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013130#endif
13131#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013132 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013133#endif
13134#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013135 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013136#endif
13137#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013138 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013139#endif
13140#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013141 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013142#endif
13143#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013144 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013145#endif
13146
13147 /* constants for waitid */
13148#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013149 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13150 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13151 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013152#endif
13153#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013154 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013155#endif
13156#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013157 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013158#endif
13159#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013160 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013161#endif
13162#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013163 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013164#endif
13165#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013166 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013167#endif
13168#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013169 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013170#endif
13171#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013172 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013173#endif
13174
13175 /* constants for lockf */
13176#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013177 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013178#endif
13179#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013180 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013181#endif
13182#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013183 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013184#endif
13185#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013186 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013187#endif
13188
Pablo Galindo4defba32018-01-27 16:16:37 +000013189#ifdef RWF_DSYNC
13190 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13191#endif
13192#ifdef RWF_HIPRI
13193 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13194#endif
13195#ifdef RWF_SYNC
13196 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13197#endif
13198#ifdef RWF_NOWAIT
13199 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13200#endif
13201
Guido van Rossum246bc171999-02-01 23:54:31 +000013202#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013203 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13204 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13205 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13206 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13207 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013208#endif
13209
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013210#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013211#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013212 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013213#endif
13214#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013215 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013216#endif
13217#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013218 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013219#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013220#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013221 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013222#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013223#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013224 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013225#endif
13226#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013227 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013228#endif
13229#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013230 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013231#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013232#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013233 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013234#endif
13235#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013236 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013237#endif
13238#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013239 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013240#endif
13241#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013242 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013243#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013244#endif
13245
Benjamin Peterson9428d532011-09-14 11:45:52 -040013246#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013247 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13248 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13249 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013250#endif
13251
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013252#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013253 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013254#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013255#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013256 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013257#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013258#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013259 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013260#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013261#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013262 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013263#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013264#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013265 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013266#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013267#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013268 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013269#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013270#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013271 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013272#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013273#if HAVE_DECL_RTLD_MEMBER
13274 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13275#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013276
Victor Stinner9b1f4742016-09-06 16:18:52 -070013277#ifdef HAVE_GETRANDOM_SYSCALL
13278 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13279 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13280#endif
13281
Victor Stinner8c62be82010-05-06 00:08:46 +000013282 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013283}
13284
13285
Martin v. Löwis1a214512008-06-11 05:26:20 +000013286static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013287 PyModuleDef_HEAD_INIT,
13288 MODNAME,
13289 posix__doc__,
13290 -1,
13291 posix_methods,
13292 NULL,
13293 NULL,
13294 NULL,
13295 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013296};
13297
13298
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013299static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013300
13301#ifdef HAVE_FACCESSAT
13302 "HAVE_FACCESSAT",
13303#endif
13304
13305#ifdef HAVE_FCHDIR
13306 "HAVE_FCHDIR",
13307#endif
13308
13309#ifdef HAVE_FCHMOD
13310 "HAVE_FCHMOD",
13311#endif
13312
13313#ifdef HAVE_FCHMODAT
13314 "HAVE_FCHMODAT",
13315#endif
13316
13317#ifdef HAVE_FCHOWN
13318 "HAVE_FCHOWN",
13319#endif
13320
Larry Hastings00964ed2013-08-12 13:49:30 -040013321#ifdef HAVE_FCHOWNAT
13322 "HAVE_FCHOWNAT",
13323#endif
13324
Larry Hastings9cf065c2012-06-22 16:30:09 -070013325#ifdef HAVE_FEXECVE
13326 "HAVE_FEXECVE",
13327#endif
13328
13329#ifdef HAVE_FDOPENDIR
13330 "HAVE_FDOPENDIR",
13331#endif
13332
Georg Brandl306336b2012-06-24 12:55:33 +020013333#ifdef HAVE_FPATHCONF
13334 "HAVE_FPATHCONF",
13335#endif
13336
Larry Hastings9cf065c2012-06-22 16:30:09 -070013337#ifdef HAVE_FSTATAT
13338 "HAVE_FSTATAT",
13339#endif
13340
13341#ifdef HAVE_FSTATVFS
13342 "HAVE_FSTATVFS",
13343#endif
13344
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013345#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013346 "HAVE_FTRUNCATE",
13347#endif
13348
Larry Hastings9cf065c2012-06-22 16:30:09 -070013349#ifdef HAVE_FUTIMENS
13350 "HAVE_FUTIMENS",
13351#endif
13352
13353#ifdef HAVE_FUTIMES
13354 "HAVE_FUTIMES",
13355#endif
13356
13357#ifdef HAVE_FUTIMESAT
13358 "HAVE_FUTIMESAT",
13359#endif
13360
13361#ifdef HAVE_LINKAT
13362 "HAVE_LINKAT",
13363#endif
13364
13365#ifdef HAVE_LCHFLAGS
13366 "HAVE_LCHFLAGS",
13367#endif
13368
13369#ifdef HAVE_LCHMOD
13370 "HAVE_LCHMOD",
13371#endif
13372
13373#ifdef HAVE_LCHOWN
13374 "HAVE_LCHOWN",
13375#endif
13376
13377#ifdef HAVE_LSTAT
13378 "HAVE_LSTAT",
13379#endif
13380
13381#ifdef HAVE_LUTIMES
13382 "HAVE_LUTIMES",
13383#endif
13384
13385#ifdef HAVE_MKDIRAT
13386 "HAVE_MKDIRAT",
13387#endif
13388
13389#ifdef HAVE_MKFIFOAT
13390 "HAVE_MKFIFOAT",
13391#endif
13392
13393#ifdef HAVE_MKNODAT
13394 "HAVE_MKNODAT",
13395#endif
13396
13397#ifdef HAVE_OPENAT
13398 "HAVE_OPENAT",
13399#endif
13400
13401#ifdef HAVE_READLINKAT
13402 "HAVE_READLINKAT",
13403#endif
13404
13405#ifdef HAVE_RENAMEAT
13406 "HAVE_RENAMEAT",
13407#endif
13408
13409#ifdef HAVE_SYMLINKAT
13410 "HAVE_SYMLINKAT",
13411#endif
13412
13413#ifdef HAVE_UNLINKAT
13414 "HAVE_UNLINKAT",
13415#endif
13416
13417#ifdef HAVE_UTIMENSAT
13418 "HAVE_UTIMENSAT",
13419#endif
13420
13421#ifdef MS_WINDOWS
13422 "MS_WINDOWS",
13423#endif
13424
13425 NULL
13426};
13427
13428
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013429PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013430INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013431{
Victor Stinner8c62be82010-05-06 00:08:46 +000013432 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013433 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013434 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013435
Brian Curtin52173d42010-12-02 18:29:18 +000013436#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013437 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013438#endif
13439
Victor Stinner8c62be82010-05-06 00:08:46 +000013440 m = PyModule_Create(&posixmodule);
13441 if (m == NULL)
13442 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013443
Victor Stinner8c62be82010-05-06 00:08:46 +000013444 /* Initialize environ dictionary */
13445 v = convertenviron();
13446 Py_XINCREF(v);
13447 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13448 return NULL;
13449 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013450
Victor Stinner8c62be82010-05-06 00:08:46 +000013451 if (all_ins(m))
13452 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013453
Victor Stinner8c62be82010-05-06 00:08:46 +000013454 if (setup_confname_tables(m))
13455 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013456
Victor Stinner8c62be82010-05-06 00:08:46 +000013457 Py_INCREF(PyExc_OSError);
13458 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013459
Guido van Rossumb3d39562000-01-31 18:41:26 +000013460#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013461 if (posix_putenv_garbage == NULL)
13462 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013463#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013464
Victor Stinner8c62be82010-05-06 00:08:46 +000013465 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013466#if defined(HAVE_WAITID) && !defined(__APPLE__)
13467 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013468 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13469 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013470#endif
13471
Christian Heimes25827622013-10-12 01:27:08 +020013472 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013473 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13474 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13475 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013476 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13477 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013478 structseq_new = StatResultType.tp_new;
13479 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013480
Christian Heimes25827622013-10-12 01:27:08 +020013481 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013482 if (PyStructSequence_InitType2(&StatVFSResultType,
13483 &statvfs_result_desc) < 0)
13484 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013485#ifdef NEED_TICKS_PER_SECOND
13486# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013487 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013488# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013489 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013490# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013491 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013492# endif
13493#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013494
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013495#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013496 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013497 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13498 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013499 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013500#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013501
13502 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013503 if (PyStructSequence_InitType2(&TerminalSizeType,
13504 &TerminalSize_desc) < 0)
13505 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013506
13507 /* initialize scandir types */
13508 if (PyType_Ready(&ScandirIteratorType) < 0)
13509 return NULL;
13510 if (PyType_Ready(&DirEntryType) < 0)
13511 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013512 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013513#if defined(HAVE_WAITID) && !defined(__APPLE__)
13514 Py_INCREF((PyObject*) &WaitidResultType);
13515 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13516#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013517 Py_INCREF((PyObject*) &StatResultType);
13518 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13519 Py_INCREF((PyObject*) &StatVFSResultType);
13520 PyModule_AddObject(m, "statvfs_result",
13521 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013522
13523#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013524 Py_INCREF(&SchedParamType);
13525 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013526#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013527
Larry Hastings605a62d2012-06-24 04:33:36 -070013528 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013529 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13530 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013531 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13532
13533 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013534 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13535 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013536 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13537
Thomas Wouters477c8d52006-05-27 19:21:47 +000013538#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013539 /*
13540 * Step 2 of weak-linking support on Mac OS X.
13541 *
13542 * The code below removes functions that are not available on the
13543 * currently active platform.
13544 *
13545 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013546 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013547 * OSX 10.4.
13548 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013549#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013550 if (fstatvfs == NULL) {
13551 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13552 return NULL;
13553 }
13554 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013555#endif /* HAVE_FSTATVFS */
13556
13557#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013558 if (statvfs == NULL) {
13559 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13560 return NULL;
13561 }
13562 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013563#endif /* HAVE_STATVFS */
13564
13565# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013566 if (lchown == NULL) {
13567 if (PyObject_DelAttrString(m, "lchown") == -1) {
13568 return NULL;
13569 }
13570 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013571#endif /* HAVE_LCHOWN */
13572
13573
13574#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013575
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013576 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013577 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13578
Larry Hastings6fe20b32012-04-19 15:07:49 -070013579 billion = PyLong_FromLong(1000000000);
13580 if (!billion)
13581 return NULL;
13582
Larry Hastings9cf065c2012-06-22 16:30:09 -070013583 /* suppress "function not used" warnings */
13584 {
13585 int ignored;
13586 fd_specified("", -1);
13587 follow_symlinks_specified("", 1);
13588 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13589 dir_fd_converter(Py_None, &ignored);
13590 dir_fd_unavailable(Py_None, &ignored);
13591 }
13592
13593 /*
13594 * provide list of locally available functions
13595 * so os.py can populate support_* lists
13596 */
13597 list = PyList_New(0);
13598 if (!list)
13599 return NULL;
13600 for (trace = have_functions; *trace; trace++) {
13601 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13602 if (!unicode)
13603 return NULL;
13604 if (PyList_Append(list, unicode))
13605 return NULL;
13606 Py_DECREF(unicode);
13607 }
13608 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013609
13610 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013611 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013612
13613 initialized = 1;
13614
Victor Stinner8c62be82010-05-06 00:08:46 +000013615 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013616}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013617
13618#ifdef __cplusplus
13619}
13620#endif