blob: 383999ea8492e883b5fa2ed80ef4aadd2695c121 [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
396#ifdef HAVE_FORK
397static void
398run_at_forkers(PyObject *lst, int reverse)
399{
400 Py_ssize_t i;
401 PyObject *cpy;
402
403 if (lst != NULL) {
404 assert(PyList_CheckExact(lst));
405
406 /* Use a list copy in case register_at_fork() is called from
407 * one of the callbacks.
408 */
409 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
410 if (cpy == NULL)
411 PyErr_WriteUnraisable(lst);
412 else {
413 if (reverse)
414 PyList_Reverse(cpy);
415 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
416 PyObject *func, *res;
417 func = PyList_GET_ITEM(cpy, i);
418 res = PyObject_CallObject(func, NULL);
419 if (res == NULL)
420 PyErr_WriteUnraisable(func);
421 else
422 Py_DECREF(res);
423 }
424 Py_DECREF(cpy);
425 }
426 }
427}
428
429void
430PyOS_BeforeFork(void)
431{
432 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
433
434 _PyImport_AcquireLock();
435}
436
437void
438PyOS_AfterFork_Parent(void)
439{
440 if (_PyImport_ReleaseLock() <= 0)
441 Py_FatalError("failed releasing import lock after fork");
442
443 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
444}
445
446void
447PyOS_AfterFork_Child(void)
448{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200449 _PyGILState_Reinit();
450 PyEval_ReInitThreads();
451 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200452 _PySignal_AfterFork();
453
454 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
455}
456
457static int
458register_at_forker(PyObject **lst, PyObject *func)
459{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700460 if (func == NULL) /* nothing to register? do nothing. */
461 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200462 if (*lst == NULL) {
463 *lst = PyList_New(0);
464 if (*lst == NULL)
465 return -1;
466 }
467 return PyList_Append(*lst, func);
468}
469#endif
470
471/* Legacy wrapper */
472void
473PyOS_AfterFork(void)
474{
475#ifdef HAVE_FORK
476 PyOS_AfterFork_Child();
477#endif
478}
479
480
Victor Stinner6036e442015-03-08 01:58:04 +0100481#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200482/* defined in fileutils.c */
483PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
484PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
485 ULONG, struct _Py_stat_struct *);
486#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700487
488#ifdef MS_WINDOWS
489static int
490win32_warn_bytes_api()
491{
492 return PyErr_WarnEx(PyExc_DeprecationWarning,
493 "The Windows bytes API has been deprecated, "
494 "use Unicode filenames instead",
495 1);
496}
497#endif
498
499
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500#ifndef MS_WINDOWS
501PyObject *
502_PyLong_FromUid(uid_t uid)
503{
504 if (uid == (uid_t)-1)
505 return PyLong_FromLong(-1);
506 return PyLong_FromUnsignedLong(uid);
507}
508
509PyObject *
510_PyLong_FromGid(gid_t gid)
511{
512 if (gid == (gid_t)-1)
513 return PyLong_FromLong(-1);
514 return PyLong_FromUnsignedLong(gid);
515}
516
517int
518_Py_Uid_Converter(PyObject *obj, void *p)
519{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 uid_t uid;
521 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200523 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 unsigned long uresult;
525
526 index = PyNumber_Index(obj);
527 if (index == NULL) {
528 PyErr_Format(PyExc_TypeError,
529 "uid should be integer, not %.200s",
530 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 return 0;
532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /*
535 * Handling uid_t is complicated for two reasons:
536 * * Although uid_t is (always?) unsigned, it still
537 * accepts -1.
538 * * We don't know its size in advance--it may be
539 * bigger than an int, or it may be smaller than
540 * a long.
541 *
542 * So a bit of defensive programming is in order.
543 * Start with interpreting the value passed
544 * in as a signed long and see if it works.
545 */
546
547 result = PyLong_AsLongAndOverflow(index, &overflow);
548
549 if (!overflow) {
550 uid = (uid_t)result;
551
552 if (result == -1) {
553 if (PyErr_Occurred())
554 goto fail;
555 /* It's a legitimate -1, we're done. */
556 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200557 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700558
559 /* Any other negative number is disallowed. */
560 if (result < 0)
561 goto underflow;
562
563 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200564 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700565 (long)uid != result)
566 goto underflow;
567 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569
570 if (overflow < 0)
571 goto underflow;
572
573 /*
574 * Okay, the value overflowed a signed long. If it
575 * fits in an *unsigned* long, it may still be okay,
576 * as uid_t may be unsigned long on this platform.
577 */
578 uresult = PyLong_AsUnsignedLong(index);
579 if (PyErr_Occurred()) {
580 if (PyErr_ExceptionMatches(PyExc_OverflowError))
581 goto overflow;
582 goto fail;
583 }
584
585 uid = (uid_t)uresult;
586
587 /*
588 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
589 * but this value would get interpreted as (uid_t)-1 by chown
590 * and its siblings. That's not what the user meant! So we
591 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100592 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700593 */
594 if (uid == (uid_t)-1)
595 goto overflow;
596
597 /* Ensure the value wasn't truncated. */
598 if (sizeof(uid_t) < sizeof(long) &&
599 (unsigned long)uid != uresult)
600 goto overflow;
601 /* fallthrough */
602
603success:
604 Py_DECREF(index);
605 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200606 return 1;
607
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700608underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200609 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700610 "uid is less than minimum");
611 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200612
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615 "uid is greater than maximum");
616 /* fallthrough */
617
618fail:
619 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 return 0;
621}
622
623int
624_Py_Gid_Converter(PyObject *obj, void *p)
625{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700626 gid_t gid;
627 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200629 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700630 unsigned long uresult;
631
632 index = PyNumber_Index(obj);
633 if (index == NULL) {
634 PyErr_Format(PyExc_TypeError,
635 "gid should be integer, not %.200s",
636 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200637 return 0;
638 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700639
640 /*
641 * Handling gid_t is complicated for two reasons:
642 * * Although gid_t is (always?) unsigned, it still
643 * accepts -1.
644 * * We don't know its size in advance--it may be
645 * bigger than an int, or it may be smaller than
646 * a long.
647 *
648 * So a bit of defensive programming is in order.
649 * Start with interpreting the value passed
650 * in as a signed long and see if it works.
651 */
652
653 result = PyLong_AsLongAndOverflow(index, &overflow);
654
655 if (!overflow) {
656 gid = (gid_t)result;
657
658 if (result == -1) {
659 if (PyErr_Occurred())
660 goto fail;
661 /* It's a legitimate -1, we're done. */
662 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200663 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700664
665 /* Any other negative number is disallowed. */
666 if (result < 0) {
667 goto underflow;
668 }
669
670 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672 (long)gid != result)
673 goto underflow;
674 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200675 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700676
677 if (overflow < 0)
678 goto underflow;
679
680 /*
681 * Okay, the value overflowed a signed long. If it
682 * fits in an *unsigned* long, it may still be okay,
683 * as gid_t may be unsigned long on this platform.
684 */
685 uresult = PyLong_AsUnsignedLong(index);
686 if (PyErr_Occurred()) {
687 if (PyErr_ExceptionMatches(PyExc_OverflowError))
688 goto overflow;
689 goto fail;
690 }
691
692 gid = (gid_t)uresult;
693
694 /*
695 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
696 * but this value would get interpreted as (gid_t)-1 by chown
697 * and its siblings. That's not what the user meant! So we
698 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100699 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700700 */
701 if (gid == (gid_t)-1)
702 goto overflow;
703
704 /* Ensure the value wasn't truncated. */
705 if (sizeof(gid_t) < sizeof(long) &&
706 (unsigned long)gid != uresult)
707 goto overflow;
708 /* fallthrough */
709
710success:
711 Py_DECREF(index);
712 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200713 return 1;
714
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700715underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200716 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700717 "gid is less than minimum");
718 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200719
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700720overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700722 "gid is greater than maximum");
723 /* fallthrough */
724
725fail:
726 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727 return 0;
728}
729#endif /* MS_WINDOWS */
730
731
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700732#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800733
734
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200735#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
736static int
737_Py_Dev_Converter(PyObject *obj, void *p)
738{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200739 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200740 if (PyErr_Occurred())
741 return 0;
742 return 1;
743}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800744#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200745
746
Larry Hastings9cf065c2012-06-22 16:30:09 -0700747#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400748/*
749 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
750 * without the int cast, the value gets interpreted as uint (4291925331),
751 * which doesn't play nicely with all the initializer lines in this file that
752 * look like this:
753 * int dir_fd = DEFAULT_DIR_FD;
754 */
755#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700756#else
757#define DEFAULT_DIR_FD (-100)
758#endif
759
760static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300761_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200762{
763 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700764 long long_value;
765
766 PyObject *index = PyNumber_Index(o);
767 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700768 return 0;
769 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700770
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300771 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 long_value = PyLong_AsLongAndOverflow(index, &overflow);
773 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300774 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200775 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700777 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700778 return 0;
779 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200780 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700782 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783 return 0;
784 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 *p = (int)long_value;
787 return 1;
788}
789
790static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200791dir_fd_converter(PyObject *o, void *p)
792{
793 if (o == Py_None) {
794 *(int *)p = DEFAULT_DIR_FD;
795 return 1;
796 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300797 else if (PyIndex_Check(o)) {
798 return _fd_converter(o, (int *)p);
799 }
800 else {
801 PyErr_Format(PyExc_TypeError,
802 "argument should be integer or None, not %.200s",
803 Py_TYPE(o)->tp_name);
804 return 0;
805 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700806}
807
808
Larry Hastings9cf065c2012-06-22 16:30:09 -0700809/*
810 * A PyArg_ParseTuple "converter" function
811 * that handles filesystem paths in the manner
812 * preferred by the os module.
813 *
814 * path_converter accepts (Unicode) strings and their
815 * subclasses, and bytes and their subclasses. What
816 * it does with the argument depends on the platform:
817 *
818 * * On Windows, if we get a (Unicode) string we
819 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700820 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700821 *
822 * * On all other platforms, strings are encoded
823 * to bytes using PyUnicode_FSConverter, then we
824 * extract the char * from the bytes object and
825 * return that.
826 *
827 * path_converter also optionally accepts signed
828 * integers (representing open file descriptors) instead
829 * of path strings.
830 *
831 * Input fields:
832 * path.nullable
833 * If nonzero, the path is permitted to be None.
834 * path.allow_fd
835 * If nonzero, the path is permitted to be a file handle
836 * (a signed int) instead of a string.
837 * path.function_name
838 * If non-NULL, path_converter will use that as the name
839 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700840 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700841 * path.argument_name
842 * If non-NULL, path_converter will use that as the name
843 * of the parameter in error messages.
844 * (If path.argument_name is NULL it uses "path".)
845 *
846 * Output fields:
847 * path.wide
848 * Points to the path if it was expressed as Unicode
849 * and was not encoded. (Only used on Windows.)
850 * path.narrow
851 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700852 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000853 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700854 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700855 * path.fd
856 * Contains a file descriptor if path.accept_fd was true
857 * and the caller provided a signed integer instead of any
858 * sort of string.
859 *
860 * WARNING: if your "path" parameter is optional, and is
861 * unspecified, path_converter will never get called.
862 * So if you set allow_fd, you *MUST* initialize path.fd = -1
863 * yourself!
864 * path.length
865 * The length of the path in characters, if specified as
866 * a string.
867 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800868 * The original object passed in (if get a PathLike object,
869 * the result of PyOS_FSPath() is treated as the original object).
870 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 * path.cleanup
872 * For internal use only. May point to a temporary object.
873 * (Pay no attention to the man behind the curtain.)
874 *
875 * At most one of path.wide or path.narrow will be non-NULL.
876 * If path was None and path.nullable was set,
877 * or if path was an integer and path.allow_fd was set,
878 * both path.wide and path.narrow will be NULL
879 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200880 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881 * path_converter takes care to not write to the path_t
882 * unless it's successful. However it must reset the
883 * "cleanup" field each time it's called.
884 *
885 * Use as follows:
886 * path_t path;
887 * memset(&path, 0, sizeof(path));
888 * PyArg_ParseTuple(args, "O&", path_converter, &path);
889 * // ... use values from path ...
890 * path_cleanup(&path);
891 *
892 * (Note that if PyArg_Parse fails you don't need to call
893 * path_cleanup(). However it is safe to do so.)
894 */
895typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100896 const char *function_name;
897 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700898 int nullable;
899 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300900 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700901#ifdef MS_WINDOWS
902 BOOL narrow;
903#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300904 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700905#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700906 int fd;
907 Py_ssize_t length;
908 PyObject *object;
909 PyObject *cleanup;
910} path_t;
911
Steve Dowercc16be82016-09-08 10:35:16 -0700912#ifdef MS_WINDOWS
913#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
914 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
915#else
Larry Hastings2f936352014-08-05 14:04:04 +1000916#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
917 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700918#endif
Larry Hastings31826802013-10-19 00:09:25 -0700919
Larry Hastings9cf065c2012-06-22 16:30:09 -0700920static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800921path_cleanup(path_t *path)
922{
923 Py_CLEAR(path->object);
924 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925}
926
927static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300928path_converter(PyObject *o, void *p)
929{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800931 PyObject *bytes = NULL;
932 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700933 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300934 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700935#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800936 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700937 const wchar_t *wide;
938#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939
940#define FORMAT_EXCEPTION(exc, fmt) \
941 PyErr_Format(exc, "%s%s" fmt, \
942 path->function_name ? path->function_name : "", \
943 path->function_name ? ": " : "", \
944 path->argument_name ? path->argument_name : "path")
945
946 /* Py_CLEANUP_SUPPORTED support */
947 if (o == NULL) {
948 path_cleanup(path);
949 return 1;
950 }
951
Brett Cannon3f9183b2016-08-26 14:44:48 -0700952 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800953 path->object = path->cleanup = NULL;
954 /* path->object owns a reference to the original object */
955 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700956
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300957 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700959#ifdef MS_WINDOWS
960 path->narrow = FALSE;
961#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700963#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800965 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 }
967
Brett Cannon3f9183b2016-08-26 14:44:48 -0700968 /* Only call this here so that we don't treat the return value of
969 os.fspath() as an fd or buffer. */
970 is_index = path->allow_fd && PyIndex_Check(o);
971 is_buffer = PyObject_CheckBuffer(o);
972 is_bytes = PyBytes_Check(o);
973 is_unicode = PyUnicode_Check(o);
974
975 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
976 /* Inline PyOS_FSPath() for better error messages. */
977 _Py_IDENTIFIER(__fspath__);
978 PyObject *func = NULL;
979
980 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
981 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800982 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700983 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800984 /* still owns a reference to the original object */
985 Py_DECREF(o);
986 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 Py_DECREF(func);
988 if (NULL == o) {
989 goto error_exit;
990 }
991 else if (PyUnicode_Check(o)) {
992 is_unicode = 1;
993 }
994 else if (PyBytes_Check(o)) {
995 is_bytes = 1;
996 }
997 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800998 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700999 }
1000 }
1001
1002 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001004 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001005 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001006 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 }
Victor Stinner59799a82013-11-13 14:17:30 +01001008 if (length > 32767) {
1009 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001012 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001013 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001015 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001016
1017 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001019 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001022 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001023 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001024 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025#endif
1026 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001027 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001028 bytes = o;
1029 Py_INCREF(bytes);
1030 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001031 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001032 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001033 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001034 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1035 "%s%s%s should be %s, not %.200s",
1036 path->function_name ? path->function_name : "",
1037 path->function_name ? ": " : "",
1038 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001039 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1040 "integer or None" :
1041 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1042 path->nullable ? "string, bytes, os.PathLike or None" :
1043 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001044 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001045 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001046 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001047 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001048 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 }
1051 }
Steve Dowercc16be82016-09-08 10:35:16 -07001052 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001053 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001054 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001055 }
1056 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001057#ifdef MS_WINDOWS
1058 path->narrow = FALSE;
1059#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001060 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001061#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001063 }
1064 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001065 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001066 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1067 path->function_name ? path->function_name : "",
1068 path->function_name ? ": " : "",
1069 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001070 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1071 "integer or None" :
1072 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1073 path->nullable ? "string, bytes, os.PathLike or None" :
1074 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001075 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001077 }
1078
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001080 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001081 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001082 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001083 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 }
1085
Steve Dowercc16be82016-09-08 10:35:16 -07001086#ifdef MS_WINDOWS
1087 wo = PyUnicode_DecodeFSDefaultAndSize(
1088 narrow,
1089 length
1090 );
1091 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001092 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001093 }
1094
Xiang Zhang04316c42017-01-08 23:26:57 +08001095 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001096 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001097 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001098 }
1099 if (length > 32767) {
1100 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001102 }
1103 if (wcslen(wide) != length) {
1104 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 path->wide = wide;
1108 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 path->cleanup = wo;
1110 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001111#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001112 path->wide = NULL;
1113 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001114 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001115 /* Still a reference owned by path->object, don't have to
1116 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001117 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001118 }
1119 else {
1120 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001122#endif
1123 path->fd = -1;
1124
1125 success_exit:
1126 path->length = length;
1127 path->object = o;
1128 return Py_CLEANUP_SUPPORTED;
1129
1130 error_exit:
1131 Py_XDECREF(o);
1132 Py_XDECREF(bytes);
1133#ifdef MS_WINDOWS
1134 Py_XDECREF(wo);
1135#endif
1136 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001137}
1138
1139static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001140argument_unavailable_error(const char *function_name, const char *argument_name)
1141{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001142 PyErr_Format(PyExc_NotImplementedError,
1143 "%s%s%s unavailable on this platform",
1144 (function_name != NULL) ? function_name : "",
1145 (function_name != NULL) ? ": ": "",
1146 argument_name);
1147}
1148
1149static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001150dir_fd_unavailable(PyObject *o, void *p)
1151{
1152 int dir_fd;
1153 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001154 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001155 if (dir_fd != DEFAULT_DIR_FD) {
1156 argument_unavailable_error(NULL, "dir_fd");
1157 return 0;
1158 }
1159 *(int *)p = dir_fd;
1160 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161}
1162
1163static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001164fd_specified(const char *function_name, int fd)
1165{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001166 if (fd == -1)
1167 return 0;
1168
1169 argument_unavailable_error(function_name, "fd");
1170 return 1;
1171}
1172
1173static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001174follow_symlinks_specified(const char *function_name, int follow_symlinks)
1175{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001176 if (follow_symlinks)
1177 return 0;
1178
1179 argument_unavailable_error(function_name, "follow_symlinks");
1180 return 1;
1181}
1182
1183static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001184path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1185{
Steve Dowercc16be82016-09-08 10:35:16 -07001186 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1187#ifndef MS_WINDOWS
1188 && !path->narrow
1189#endif
1190 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001191 PyErr_Format(PyExc_ValueError,
1192 "%s: can't specify dir_fd without matching path",
1193 function_name);
1194 return 1;
1195 }
1196 return 0;
1197}
1198
1199static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001200dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1201{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001202 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1203 PyErr_Format(PyExc_ValueError,
1204 "%s: can't specify both dir_fd and fd",
1205 function_name);
1206 return 1;
1207 }
1208 return 0;
1209}
1210
1211static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001212fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1213 int follow_symlinks)
1214{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001215 if ((fd > 0) && (!follow_symlinks)) {
1216 PyErr_Format(PyExc_ValueError,
1217 "%s: cannot use fd and follow_symlinks together",
1218 function_name);
1219 return 1;
1220 }
1221 return 0;
1222}
1223
1224static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001225dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1226 int follow_symlinks)
1227{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001228 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1229 PyErr_Format(PyExc_ValueError,
1230 "%s: cannot use dir_fd and follow_symlinks together",
1231 function_name);
1232 return 1;
1233 }
1234 return 0;
1235}
1236
Larry Hastings2f936352014-08-05 14:04:04 +10001237#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001238 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001239#else
Larry Hastings2f936352014-08-05 14:04:04 +10001240 typedef off_t Py_off_t;
1241#endif
1242
1243static int
1244Py_off_t_converter(PyObject *arg, void *addr)
1245{
1246#ifdef HAVE_LARGEFILE_SUPPORT
1247 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1248#else
1249 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001250#endif
1251 if (PyErr_Occurred())
1252 return 0;
1253 return 1;
1254}
Larry Hastings2f936352014-08-05 14:04:04 +10001255
1256static PyObject *
1257PyLong_FromPy_off_t(Py_off_t offset)
1258{
1259#ifdef HAVE_LARGEFILE_SUPPORT
1260 return PyLong_FromLongLong(offset);
1261#else
1262 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001263#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001264}
1265
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001266#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001267
1268static int
Brian Curtind25aef52011-06-13 15:16:04 -05001269win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001270{
Martin Panter70214ad2016-08-04 02:38:59 +00001271 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1272 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274
1275 if (0 == DeviceIoControl(
1276 reparse_point_handle,
1277 FSCTL_GET_REPARSE_POINT,
1278 NULL, 0, /* in buffer */
1279 target_buffer, sizeof(target_buffer),
1280 &n_bytes_returned,
1281 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001282 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001283
1284 if (reparse_tag)
1285 *reparse_tag = rdb->ReparseTag;
1286
Brian Curtind25aef52011-06-13 15:16:04 -05001287 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001288}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001289
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001290#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001291
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001293#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001294/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001295** environ directly, we must obtain it with _NSGetEnviron(). See also
1296** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001297*/
1298#include <crt_externs.h>
1299static char **environ;
1300#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001302#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303
Barry Warsaw53699e91996-12-10 23:23:01 +00001304static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001305convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
Victor Stinner8c62be82010-05-06 00:08:46 +00001307 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001308#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001310#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001313
Victor Stinner8c62be82010-05-06 00:08:46 +00001314 d = PyDict_New();
1315 if (d == NULL)
1316 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001317#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 if (environ == NULL)
1319 environ = *_NSGetEnviron();
1320#endif
1321#ifdef MS_WINDOWS
1322 /* _wenviron must be initialized in this way if the program is started
1323 through main() instead of wmain(). */
1324 _wgetenv(L"");
1325 if (_wenviron == NULL)
1326 return d;
1327 /* This part ignores errors */
1328 for (e = _wenviron; *e != NULL; e++) {
1329 PyObject *k;
1330 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001331 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 if (p == NULL)
1333 continue;
1334 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1335 if (k == NULL) {
1336 PyErr_Clear();
1337 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001338 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001339 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1340 if (v == NULL) {
1341 PyErr_Clear();
1342 Py_DECREF(k);
1343 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001344 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 if (PyDict_GetItem(d, k) == NULL) {
1346 if (PyDict_SetItem(d, k, v) != 0)
1347 PyErr_Clear();
1348 }
1349 Py_DECREF(k);
1350 Py_DECREF(v);
1351 }
1352#else
1353 if (environ == NULL)
1354 return d;
1355 /* This part ignores errors */
1356 for (e = environ; *e != NULL; e++) {
1357 PyObject *k;
1358 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001359 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 if (p == NULL)
1361 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001362 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 if (k == NULL) {
1364 PyErr_Clear();
1365 continue;
1366 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001367 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 if (v == NULL) {
1369 PyErr_Clear();
1370 Py_DECREF(k);
1371 continue;
1372 }
1373 if (PyDict_GetItem(d, k) == NULL) {
1374 if (PyDict_SetItem(d, k, v) != 0)
1375 PyErr_Clear();
1376 }
1377 Py_DECREF(k);
1378 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001379 }
1380#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001382}
1383
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001384/* Set a POSIX-specific error from errno, and return NULL */
1385
Barry Warsawd58d7641998-07-23 16:14:40 +00001386static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001387posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001388{
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390}
Mark Hammondef8b6542001-05-13 08:04:26 +00001391
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001392#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001393static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001394win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001395{
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 /* XXX We should pass the function name along in the future.
1397 (winreg.c also wants to pass the function name.)
1398 This would however require an additional param to the
1399 Windows error object, which is non-trivial.
1400 */
1401 errno = GetLastError();
1402 if (filename)
1403 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1404 else
1405 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001406}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001407
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001408static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001409win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001410{
1411 /* XXX - see win32_error for comments on 'function' */
1412 errno = GetLastError();
1413 if (filename)
1414 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001415 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001416 errno,
1417 filename);
1418 else
1419 return PyErr_SetFromWindowsErr(errno);
1420}
1421
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001422#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423
Larry Hastings9cf065c2012-06-22 16:30:09 -07001424static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001425posix_path_object_error(PyObject *path)
1426{
1427 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1428}
1429
1430static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001431path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432{
1433#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001434 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1435 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436#else
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001437 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001438#endif
1439}
1440
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001441static PyObject *
1442path_object_error2(PyObject *path, PyObject *path2)
1443{
1444#ifdef MS_WINDOWS
1445 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1446 PyExc_OSError, 0, path, path2);
1447#else
1448 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1449#endif
1450}
1451
1452static PyObject *
1453path_error(path_t *path)
1454{
1455 return path_object_error(path->object);
1456}
Larry Hastings31826802013-10-19 00:09:25 -07001457
Larry Hastingsb0827312014-02-09 22:05:19 -08001458static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001459posix_path_error(path_t *path)
1460{
1461 return posix_path_object_error(path->object);
1462}
1463
1464static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001465path_error2(path_t *path, path_t *path2)
1466{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001467 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001468}
1469
1470
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001471/* POSIX generic methods */
1472
Larry Hastings2f936352014-08-05 14:04:04 +10001473static int
1474fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001475{
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001477 int *pointer = (int *)p;
1478 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001479 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001480 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001481 *pointer = fd;
1482 return 1;
1483}
1484
1485static PyObject *
1486posix_fildes_fd(int fd, int (*func)(int))
1487{
1488 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001489 int async_err = 0;
1490
1491 do {
1492 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001493 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001494 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001495 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001496 Py_END_ALLOW_THREADS
1497 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1498 if (res != 0)
1499 return (!async_err) ? posix_error() : NULL;
1500 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001501}
Guido van Rossum21142a01999-01-08 21:05:37 +00001502
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001504#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505/* This is a reimplementation of the C library's chdir function,
1506 but one that produces Win32 errors instead of DOS error codes.
1507 chdir is essentially a wrapper around SetCurrentDirectory; however,
1508 it also needs to set "magic" environment variables indicating
1509 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001510static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511win32_wchdir(LPCWSTR path)
1512{
Victor Stinnered537822015-12-13 21:40:26 +01001513 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 int result;
1515 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 if(!SetCurrentDirectoryW(path))
1518 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001519 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 if (!result)
1521 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001522 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001523 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 if (!new_path) {
1525 SetLastError(ERROR_OUTOFMEMORY);
1526 return FALSE;
1527 }
1528 result = GetCurrentDirectoryW(result, new_path);
1529 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001530 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001531 return FALSE;
1532 }
1533 }
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001534 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1535 wcsncmp(new_path, L"//", 2) == 0);
1536 if (!is_unc_like_path) {
1537 env[1] = new_path[0];
1538 result = SetEnvironmentVariableW(env, new_path);
1539 }
Victor Stinnered537822015-12-13 21:40:26 +01001540 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001541 PyMem_RawFree(new_path);
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001542 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543}
1544#endif
1545
Martin v. Löwis14694662006-02-03 12:54:16 +00001546#ifdef MS_WINDOWS
1547/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1548 - time stamps are restricted to second resolution
1549 - file modification times suffer from forth-and-back conversions between
1550 UTC and local time
1551 Therefore, we implement our own stat, based on the Win32 API directly.
1552*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001553#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001554#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001555
Victor Stinner6036e442015-03-08 01:58:04 +01001556static void
Steve Dowercc16be82016-09-08 10:35:16 -07001557find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1558 BY_HANDLE_FILE_INFORMATION *info,
1559 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001560{
1561 memset(info, 0, sizeof(*info));
1562 info->dwFileAttributes = pFileData->dwFileAttributes;
1563 info->ftCreationTime = pFileData->ftCreationTime;
1564 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1565 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1566 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1567 info->nFileSizeLow = pFileData->nFileSizeLow;
1568/* info->nNumberOfLinks = 1; */
1569 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1570 *reparse_tag = pFileData->dwReserved0;
1571 else
1572 *reparse_tag = 0;
1573}
1574
Guido van Rossumd8faa362007-04-27 19:54:29 +00001575static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001576attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001577{
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 HANDLE hFindFile;
1579 WIN32_FIND_DATAW FileData;
1580 hFindFile = FindFirstFileW(pszFile, &FileData);
1581 if (hFindFile == INVALID_HANDLE_VALUE)
1582 return FALSE;
1583 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001584 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001585 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001586}
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588static BOOL
1589get_target_path(HANDLE hdl, wchar_t **target_path)
1590{
1591 int buf_size, result_length;
1592 wchar_t *buf;
1593
1594 /* We have a good handle to the target, use it to determine
1595 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001596 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1597 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001598 if(!buf_size)
1599 return FALSE;
1600
Victor Stinnerc36674a2016-03-16 14:30:16 +01001601 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001602 if (!buf) {
1603 SetLastError(ERROR_OUTOFMEMORY);
1604 return FALSE;
1605 }
1606
Steve Dower2ea51c92015-03-20 21:49:12 -07001607 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001608 buf, buf_size, VOLUME_NAME_DOS);
1609
1610 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001611 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001612 return FALSE;
1613 }
1614
1615 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001616 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001617 return FALSE;
1618 }
1619
1620 buf[result_length] = 0;
1621
1622 *target_path = buf;
1623 return TRUE;
1624}
1625
1626static int
Steve Dowercc16be82016-09-08 10:35:16 -07001627win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001628 BOOL traverse)
1629{
Victor Stinner26de69d2011-06-17 15:15:38 +02001630 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001631 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001633 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001634 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001635 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636
Steve Dowercc16be82016-09-08 10:35:16 -07001637 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001638 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001639 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001640 0, /* share mode */
1641 NULL, /* security attributes */
1642 OPEN_EXISTING,
1643 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001644 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1645 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001646 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001647 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1648 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001649 NULL);
1650
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001651 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001652 /* Either the target doesn't exist, or we don't have access to
1653 get a handle to it. If the former, we need to return an error.
1654 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001655 DWORD lastError = GetLastError();
1656 if (lastError != ERROR_ACCESS_DENIED &&
1657 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 return -1;
1659 /* Could not get attributes on open file. Fall back to
1660 reading the directory. */
1661 if (!attributes_from_dir(path, &info, &reparse_tag))
1662 /* Very strange. This should not fail now */
1663 return -1;
1664 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1665 if (traverse) {
1666 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001667 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001668 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001671 } else {
1672 if (!GetFileInformationByHandle(hFile, &info)) {
1673 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001674 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 }
1676 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001677 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1678 return -1;
1679
1680 /* Close the outer open file handle now that we're about to
1681 reopen it with different flags. */
1682 if (!CloseHandle(hFile))
1683 return -1;
1684
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001686 /* In order to call GetFinalPathNameByHandle we need to open
1687 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001688 hFile2 = CreateFileW(
1689 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1690 NULL, OPEN_EXISTING,
1691 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1692 NULL);
1693 if (hFile2 == INVALID_HANDLE_VALUE)
1694 return -1;
1695
1696 if (!get_target_path(hFile2, &target_path))
1697 return -1;
1698
Steve Dowercc16be82016-09-08 10:35:16 -07001699 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001700 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001701 return code;
1702 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001703 } else
1704 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001706 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001707
1708 /* Set S_IEXEC if it is an .exe, .bat, ... */
1709 dot = wcsrchr(path, '.');
1710 if (dot) {
1711 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1712 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1713 result->st_mode |= 0111;
1714 }
1715 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716}
1717
1718static int
Steve Dowercc16be82016-09-08 10:35:16 -07001719win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 /* Protocol violation: we explicitly clear errno, instead of
1722 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001723 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001724 errno = 0;
1725 return code;
1726}
Brian Curtind25aef52011-06-13 15:16:04 -05001727/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001728
1729 In Posix, stat automatically traverses symlinks and returns the stat
1730 structure for the target. In Windows, the equivalent GetFileAttributes by
1731 default does not traverse symlinks and instead returns attributes for
1732 the symlink.
1733
1734 Therefore, win32_lstat will get the attributes traditionally, and
1735 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001736 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001737
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001738static int
Steve Dowercc16be82016-09-08 10:35:16 -07001739win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001740{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001741 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001742}
1743
Victor Stinner8c62be82010-05-06 00:08:46 +00001744static int
Steve Dowercc16be82016-09-08 10:35:16 -07001745win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001746{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001747 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001748}
1749
Martin v. Löwis14694662006-02-03 12:54:16 +00001750#endif /* MS_WINDOWS */
1751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001753"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001755 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1757\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001758Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1759or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001760\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762
1763static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_mode", "protection bits"},
1765 {"st_ino", "inode"},
1766 {"st_dev", "device"},
1767 {"st_nlink", "number of hard links"},
1768 {"st_uid", "user ID of owner"},
1769 {"st_gid", "group ID of owner"},
1770 {"st_size", "total size, in bytes"},
1771 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1772 {NULL, "integer time of last access"},
1773 {NULL, "integer time of last modification"},
1774 {NULL, "integer time of last change"},
1775 {"st_atime", "time of last access"},
1776 {"st_mtime", "time of last modification"},
1777 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001778 {"st_atime_ns", "time of last access in nanoseconds"},
1779 {"st_mtime_ns", "time of last modification in nanoseconds"},
1780 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001781#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001787#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001790#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001792#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001793#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001795#endif
1796#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001798#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001799#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1800 {"st_file_attributes", "Windows file attribute bits"},
1801#endif
jcea6c51d512018-01-28 14:00:08 +01001802#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1803 {"st_fstype", "Type of filesystem"},
1804#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806};
1807
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001808#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001809#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001810#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001811#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812#endif
1813
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001814#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001815#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1816#else
1817#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1818#endif
1819
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001820#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001821#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1822#else
1823#define ST_RDEV_IDX ST_BLOCKS_IDX
1824#endif
1825
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001826#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1827#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1828#else
1829#define ST_FLAGS_IDX ST_RDEV_IDX
1830#endif
1831
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001832#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001833#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001834#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001835#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#endif
1837
1838#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1839#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1840#else
1841#define ST_BIRTHTIME_IDX ST_GEN_IDX
1842#endif
1843
Zachary Ware63f277b2014-06-19 09:46:37 -05001844#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1845#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1846#else
1847#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1848#endif
1849
jcea6c51d512018-01-28 14:00:08 +01001850#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1851#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1852#else
1853#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1854#endif
1855
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 "stat_result", /* name */
1858 stat_result__doc__, /* doc */
1859 stat_result_fields,
1860 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861};
1862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001863PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1865This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001867or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001870
1871static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001872 {"f_bsize", },
1873 {"f_frsize", },
1874 {"f_blocks", },
1875 {"f_bfree", },
1876 {"f_bavail", },
1877 {"f_files", },
1878 {"f_ffree", },
1879 {"f_favail", },
1880 {"f_flag", },
1881 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001882 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001884};
1885
1886static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 "statvfs_result", /* name */
1888 statvfs_result__doc__, /* doc */
1889 statvfs_result_fields,
1890 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001891};
1892
Ross Lagerwall7807c352011-03-17 20:20:30 +02001893#if defined(HAVE_WAITID) && !defined(__APPLE__)
1894PyDoc_STRVAR(waitid_result__doc__,
1895"waitid_result: Result from waitid.\n\n\
1896This object may be accessed either as a tuple of\n\
1897 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1898or via the attributes si_pid, si_uid, and so on.\n\
1899\n\
1900See os.waitid for more information.");
1901
1902static PyStructSequence_Field waitid_result_fields[] = {
1903 {"si_pid", },
1904 {"si_uid", },
1905 {"si_signo", },
1906 {"si_status", },
1907 {"si_code", },
1908 {0}
1909};
1910
1911static PyStructSequence_Desc waitid_result_desc = {
1912 "waitid_result", /* name */
1913 waitid_result__doc__, /* doc */
1914 waitid_result_fields,
1915 5
1916};
1917static PyTypeObject WaitidResultType;
1918#endif
1919
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001920static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921static PyTypeObject StatResultType;
1922static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001923#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001924static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001925#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001926static newfunc structseq_new;
1927
1928static PyObject *
1929statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1930{
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 PyStructSequence *result;
1932 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 result = (PyStructSequence*)structseq_new(type, args, kwds);
1935 if (!result)
1936 return NULL;
1937 /* If we have been initialized from a tuple,
1938 st_?time might be set to None. Initialize it
1939 from the int slots. */
1940 for (i = 7; i <= 9; i++) {
1941 if (result->ob_item[i+3] == Py_None) {
1942 Py_DECREF(Py_None);
1943 Py_INCREF(result->ob_item[i]);
1944 result->ob_item[i+3] = result->ob_item[i];
1945 }
1946 }
1947 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001948}
1949
1950
Larry Hastings6fe20b32012-04-19 15:07:49 -07001951static PyObject *billion = NULL;
1952
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001953static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001954fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001955{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001956 PyObject *s = _PyLong_FromTime_t(sec);
1957 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1958 PyObject *s_in_ns = NULL;
1959 PyObject *ns_total = NULL;
1960 PyObject *float_s = NULL;
1961
1962 if (!(s && ns_fractional))
1963 goto exit;
1964
1965 s_in_ns = PyNumber_Multiply(s, billion);
1966 if (!s_in_ns)
1967 goto exit;
1968
1969 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1970 if (!ns_total)
1971 goto exit;
1972
Victor Stinner01b5aab2017-10-24 02:02:00 -07001973 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1974 if (!float_s) {
1975 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001976 }
1977
1978 PyStructSequence_SET_ITEM(v, index, s);
1979 PyStructSequence_SET_ITEM(v, index+3, float_s);
1980 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1981 s = NULL;
1982 float_s = NULL;
1983 ns_total = NULL;
1984exit:
1985 Py_XDECREF(s);
1986 Py_XDECREF(ns_fractional);
1987 Py_XDECREF(s_in_ns);
1988 Py_XDECREF(ns_total);
1989 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001990}
1991
Tim Peters5aa91602002-01-30 05:46:57 +00001992/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001993 (used by posix_stat() and posix_fstat()) */
1994static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001995_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001996{
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 unsigned long ansec, mnsec, cnsec;
1998 PyObject *v = PyStructSequence_New(&StatResultType);
1999 if (v == NULL)
2000 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002001
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002003 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002004 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002005#ifdef MS_WINDOWS
2006 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002007#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002008 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002011#if defined(MS_WINDOWS)
2012 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2013 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2014#else
2015 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2016 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2017#endif
xdegaye50e86032017-05-22 11:15:08 +02002018 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2019 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002020
Martin v. Löwis14694662006-02-03 12:54:16 +00002021#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 ansec = st->st_atim.tv_nsec;
2023 mnsec = st->st_mtim.tv_nsec;
2024 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002025#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 ansec = st->st_atimespec.tv_nsec;
2027 mnsec = st->st_mtimespec.tv_nsec;
2028 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002029#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 ansec = st->st_atime_nsec;
2031 mnsec = st->st_mtime_nsec;
2032 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002033#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002036 fill_time(v, 7, st->st_atime, ansec);
2037 fill_time(v, 8, st->st_mtime, mnsec);
2038 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002039
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002040#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2042 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002043#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002044#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2046 PyLong_FromLong((long)st->st_blocks));
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_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2050 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002051#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002052#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2054 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002055#endif
2056#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002058 PyObject *val;
2059 unsigned long bsec,bnsec;
2060 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002061#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002062 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002063#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002064 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002065#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002066 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002067 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2068 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002070#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002071#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2073 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002074#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002075#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2076 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2077 PyLong_FromUnsignedLong(st->st_file_attributes));
2078#endif
jcea6c51d512018-01-28 14:00:08 +01002079#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2080 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2081 PyUnicode_FromString(st->st_fstype));
2082#endif
Fred Drake699f3522000-06-29 21:12:41 +00002083
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 if (PyErr_Occurred()) {
2085 Py_DECREF(v);
2086 return NULL;
2087 }
Fred Drake699f3522000-06-29 21:12:41 +00002088
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002090}
2091
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092/* POSIX methods */
2093
Guido van Rossum94f6f721999-01-06 18:42:14 +00002094
2095static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002096posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002097 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002098{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002099 STRUCT_STAT st;
2100 int result;
2101
2102#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2103 if (follow_symlinks_specified(function_name, follow_symlinks))
2104 return NULL;
2105#endif
2106
2107 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2108 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2109 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2110 return NULL;
2111
2112 Py_BEGIN_ALLOW_THREADS
2113 if (path->fd != -1)
2114 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002115#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002116 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002117 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002118 else
Steve Dowercc16be82016-09-08 10:35:16 -07002119 result = win32_lstat(path->wide, &st);
2120#else
2121 else
2122#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002123 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2124 result = LSTAT(path->narrow, &st);
2125 else
Steve Dowercc16be82016-09-08 10:35:16 -07002126#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002127#ifdef HAVE_FSTATAT
2128 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2129 result = fstatat(dir_fd, path->narrow, &st,
2130 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2131 else
Steve Dowercc16be82016-09-08 10:35:16 -07002132#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002133 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002134#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002135 Py_END_ALLOW_THREADS
2136
Victor Stinner292c8352012-10-30 02:17:38 +01002137 if (result != 0) {
2138 return path_error(path);
2139 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002140
2141 return _pystat_fromstructstat(&st);
2142}
2143
Larry Hastings2f936352014-08-05 14:04:04 +10002144/*[python input]
2145
2146for s in """
2147
2148FACCESSAT
2149FCHMODAT
2150FCHOWNAT
2151FSTATAT
2152LINKAT
2153MKDIRAT
2154MKFIFOAT
2155MKNODAT
2156OPENAT
2157READLINKAT
2158SYMLINKAT
2159UNLINKAT
2160
2161""".strip().split():
2162 s = s.strip()
2163 print("""
2164#ifdef HAVE_{s}
2165 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002166#else
Larry Hastings2f936352014-08-05 14:04:04 +10002167 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002168#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002169""".rstrip().format(s=s))
2170
2171for s in """
2172
2173FCHDIR
2174FCHMOD
2175FCHOWN
2176FDOPENDIR
2177FEXECVE
2178FPATHCONF
2179FSTATVFS
2180FTRUNCATE
2181
2182""".strip().split():
2183 s = s.strip()
2184 print("""
2185#ifdef HAVE_{s}
2186 #define PATH_HAVE_{s} 1
2187#else
2188 #define PATH_HAVE_{s} 0
2189#endif
2190
2191""".rstrip().format(s=s))
2192[python start generated code]*/
2193
2194#ifdef HAVE_FACCESSAT
2195 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_FCHMODAT
2201 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_FCHOWNAT
2207 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2208#else
2209 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2210#endif
2211
2212#ifdef HAVE_FSTATAT
2213 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_LINKAT
2219 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_MKDIRAT
2225 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_MKFIFOAT
2231 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_MKNODAT
2237 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_OPENAT
2243 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_READLINKAT
2249 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_SYMLINKAT
2255 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_UNLINKAT
2261 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_FCHDIR
2267 #define PATH_HAVE_FCHDIR 1
2268#else
2269 #define PATH_HAVE_FCHDIR 0
2270#endif
2271
2272#ifdef HAVE_FCHMOD
2273 #define PATH_HAVE_FCHMOD 1
2274#else
2275 #define PATH_HAVE_FCHMOD 0
2276#endif
2277
2278#ifdef HAVE_FCHOWN
2279 #define PATH_HAVE_FCHOWN 1
2280#else
2281 #define PATH_HAVE_FCHOWN 0
2282#endif
2283
2284#ifdef HAVE_FDOPENDIR
2285 #define PATH_HAVE_FDOPENDIR 1
2286#else
2287 #define PATH_HAVE_FDOPENDIR 0
2288#endif
2289
2290#ifdef HAVE_FEXECVE
2291 #define PATH_HAVE_FEXECVE 1
2292#else
2293 #define PATH_HAVE_FEXECVE 0
2294#endif
2295
2296#ifdef HAVE_FPATHCONF
2297 #define PATH_HAVE_FPATHCONF 1
2298#else
2299 #define PATH_HAVE_FPATHCONF 0
2300#endif
2301
2302#ifdef HAVE_FSTATVFS
2303 #define PATH_HAVE_FSTATVFS 1
2304#else
2305 #define PATH_HAVE_FSTATVFS 0
2306#endif
2307
2308#ifdef HAVE_FTRUNCATE
2309 #define PATH_HAVE_FTRUNCATE 1
2310#else
2311 #define PATH_HAVE_FTRUNCATE 0
2312#endif
2313/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002314
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002315#ifdef MS_WINDOWS
2316 #undef PATH_HAVE_FTRUNCATE
2317 #define PATH_HAVE_FTRUNCATE 1
2318#endif
Larry Hastings31826802013-10-19 00:09:25 -07002319
Larry Hastings61272b72014-01-07 12:41:53 -08002320/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002321
2322class path_t_converter(CConverter):
2323
2324 type = "path_t"
2325 impl_by_reference = True
2326 parse_by_reference = True
2327
2328 converter = 'path_converter'
2329
2330 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002331 # right now path_t doesn't support default values.
2332 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002333 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002334 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002335
Larry Hastings2f936352014-08-05 14:04:04 +10002336 if self.c_default not in (None, 'Py_None'):
2337 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002338
2339 self.nullable = nullable
2340 self.allow_fd = allow_fd
2341
Larry Hastings7726ac92014-01-31 22:03:12 -08002342 def pre_render(self):
2343 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002344 if isinstance(value, str):
2345 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002346 return str(int(bool(value)))
2347
2348 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002349 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002350 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002351 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002352 strify(self.nullable),
2353 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002354 )
2355
2356 def cleanup(self):
2357 return "path_cleanup(&" + self.name + ");\n"
2358
2359
2360class dir_fd_converter(CConverter):
2361 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002362
Larry Hastings2f936352014-08-05 14:04:04 +10002363 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002364 if self.default in (unspecified, None):
2365 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002366 if isinstance(requires, str):
2367 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2368 else:
2369 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002370
Larry Hastings2f936352014-08-05 14:04:04 +10002371class fildes_converter(CConverter):
2372 type = 'int'
2373 converter = 'fildes_converter'
2374
2375class uid_t_converter(CConverter):
2376 type = "uid_t"
2377 converter = '_Py_Uid_Converter'
2378
2379class gid_t_converter(CConverter):
2380 type = "gid_t"
2381 converter = '_Py_Gid_Converter'
2382
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002383class dev_t_converter(CConverter):
2384 type = 'dev_t'
2385 converter = '_Py_Dev_Converter'
2386
2387class dev_t_return_converter(unsigned_long_return_converter):
2388 type = 'dev_t'
2389 conversion_fn = '_PyLong_FromDev'
2390 unsigned_cast = '(dev_t)'
2391
Larry Hastings2f936352014-08-05 14:04:04 +10002392class FSConverter_converter(CConverter):
2393 type = 'PyObject *'
2394 converter = 'PyUnicode_FSConverter'
2395 def converter_init(self):
2396 if self.default is not unspecified:
2397 fail("FSConverter_converter does not support default values")
2398 self.c_default = 'NULL'
2399
2400 def cleanup(self):
2401 return "Py_XDECREF(" + self.name + ");\n"
2402
2403class pid_t_converter(CConverter):
2404 type = 'pid_t'
2405 format_unit = '" _Py_PARSE_PID "'
2406
2407class idtype_t_converter(int_converter):
2408 type = 'idtype_t'
2409
2410class id_t_converter(CConverter):
2411 type = 'id_t'
2412 format_unit = '" _Py_PARSE_PID "'
2413
Benjamin Petersonca470632016-09-06 13:47:26 -07002414class intptr_t_converter(CConverter):
2415 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002416 format_unit = '" _Py_PARSE_INTPTR "'
2417
2418class Py_off_t_converter(CConverter):
2419 type = 'Py_off_t'
2420 converter = 'Py_off_t_converter'
2421
2422class Py_off_t_return_converter(long_return_converter):
2423 type = 'Py_off_t'
2424 conversion_fn = 'PyLong_FromPy_off_t'
2425
2426class path_confname_converter(CConverter):
2427 type="int"
2428 converter="conv_path_confname"
2429
2430class confstr_confname_converter(path_confname_converter):
2431 converter='conv_confstr_confname'
2432
2433class sysconf_confname_converter(path_confname_converter):
2434 converter="conv_sysconf_confname"
2435
2436class sched_param_converter(CConverter):
2437 type = 'struct sched_param'
2438 converter = 'convert_sched_param'
2439 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002440
Larry Hastings61272b72014-01-07 12:41:53 -08002441[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002442/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002443
Larry Hastings61272b72014-01-07 12:41:53 -08002444/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002445
Larry Hastings2a727912014-01-16 11:32:01 -08002446os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002447
2448 path : path_t(allow_fd=True)
BNMetrics08026b12018-11-02 17:56:25 +00002449 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002450 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002451
2452 *
2453
Larry Hastings2f936352014-08-05 14:04:04 +10002454 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002455 If not None, it should be a file descriptor open to a directory,
2456 and path should be a relative string; path will then be relative to
2457 that directory.
2458
2459 follow_symlinks: bool = True
2460 If False, and the last element of the path is a symbolic link,
2461 stat will examine the symbolic link itself instead of the file
2462 the link points to.
2463
2464Perform a stat system call on the given path.
2465
2466dir_fd and follow_symlinks may not be implemented
2467 on your platform. If they are unavailable, using them will raise a
2468 NotImplementedError.
2469
2470It's an error to use dir_fd or follow_symlinks when specifying path as
2471 an open file descriptor.
2472
Larry Hastings61272b72014-01-07 12:41:53 -08002473[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002474
Larry Hastings31826802013-10-19 00:09:25 -07002475static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002476os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002477/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002478{
2479 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2480}
2481
Larry Hastings2f936352014-08-05 14:04:04 +10002482
2483/*[clinic input]
2484os.lstat
2485
2486 path : path_t
2487
2488 *
2489
2490 dir_fd : dir_fd(requires='fstatat') = None
2491
2492Perform a stat system call on the given path, without following symbolic links.
2493
2494Like stat(), but do not follow symbolic links.
2495Equivalent to stat(path, follow_symlinks=False).
2496[clinic start generated code]*/
2497
Larry Hastings2f936352014-08-05 14:04:04 +10002498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002499os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2500/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002501{
2502 int follow_symlinks = 0;
2503 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2504}
Larry Hastings31826802013-10-19 00:09:25 -07002505
Larry Hastings2f936352014-08-05 14:04:04 +10002506
Larry Hastings61272b72014-01-07 12:41:53 -08002507/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002508os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002509
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002510 path: path_t
BNMetrics08026b12018-11-02 17:56:25 +00002511 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002512
2513 mode: int
2514 Operating-system mode bitfield. Can be F_OK to test existence,
2515 or the inclusive-OR of R_OK, W_OK, and X_OK.
2516
2517 *
2518
Larry Hastings2f936352014-08-05 14:04:04 +10002519 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002520 If not None, it should be a file descriptor open to a directory,
2521 and path should be relative; path will then be relative to that
2522 directory.
2523
2524 effective_ids: bool = False
2525 If True, access will use the effective uid/gid instead of
2526 the real uid/gid.
2527
2528 follow_symlinks: bool = True
2529 If False, and the last element of the path is a symbolic link,
2530 access will examine the symbolic link itself instead of the file
2531 the link points to.
2532
2533Use the real uid/gid to test for access to a path.
2534
2535{parameters}
2536dir_fd, effective_ids, and follow_symlinks may not be implemented
2537 on your platform. If they are unavailable, using them will raise a
2538 NotImplementedError.
2539
2540Note that most operations will use the effective uid/gid, therefore this
2541 routine can be used in a suid/sgid environment to test if the invoking user
2542 has the specified access to the path.
2543
Larry Hastings61272b72014-01-07 12:41:53 -08002544[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002545
Larry Hastings2f936352014-08-05 14:04:04 +10002546static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002547os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002548 int effective_ids, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002549/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002550{
Larry Hastings2f936352014-08-05 14:04:04 +10002551 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002552
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002553#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002554 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002555#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002556 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002557#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559#ifndef HAVE_FACCESSAT
2560 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002561 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562
2563 if (effective_ids) {
2564 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002565 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002566 }
2567#endif
2568
2569#ifdef MS_WINDOWS
2570 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002571 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 Py_END_ALLOW_THREADS
2573
2574 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002575 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576 * * we didn't get a -1, and
2577 * * write access wasn't requested,
2578 * * or the file isn't read-only,
2579 * * or it's a directory.
2580 * (Directories cannot be read-only on Windows.)
2581 */
Larry Hastings2f936352014-08-05 14:04:04 +10002582 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002583 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002585 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002586#else
2587
2588 Py_BEGIN_ALLOW_THREADS
2589#ifdef HAVE_FACCESSAT
2590 if ((dir_fd != DEFAULT_DIR_FD) ||
2591 effective_ids ||
2592 !follow_symlinks) {
2593 int flags = 0;
2594 if (!follow_symlinks)
2595 flags |= AT_SYMLINK_NOFOLLOW;
2596 if (effective_ids)
2597 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002598 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599 }
2600 else
2601#endif
Larry Hastings31826802013-10-19 00:09:25 -07002602 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002604 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605#endif
2606
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002608}
2609
Guido van Rossumd371ff11999-01-25 16:12:23 +00002610#ifndef F_OK
2611#define F_OK 0
2612#endif
2613#ifndef R_OK
2614#define R_OK 4
2615#endif
2616#ifndef W_OK
2617#define W_OK 2
2618#endif
2619#ifndef X_OK
2620#define X_OK 1
2621#endif
2622
Larry Hastings31826802013-10-19 00:09:25 -07002623
Guido van Rossumd371ff11999-01-25 16:12:23 +00002624#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002625/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002626os.ttyname -> DecodeFSDefault
2627
2628 fd: int
2629 Integer file descriptor handle.
2630
2631 /
2632
2633Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002634[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002635
Larry Hastings31826802013-10-19 00:09:25 -07002636static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002637os_ttyname_impl(PyObject *module, int fd)
2638/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002639{
2640 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002641
Larry Hastings31826802013-10-19 00:09:25 -07002642 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002643 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002644 posix_error();
2645 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002646}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002647#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002648
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002649#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002650/*[clinic input]
2651os.ctermid
2652
2653Return the name of the controlling terminal for this process.
2654[clinic start generated code]*/
2655
Larry Hastings2f936352014-08-05 14:04:04 +10002656static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002657os_ctermid_impl(PyObject *module)
2658/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659{
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 char *ret;
2661 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002662
Greg Wardb48bc172000-03-01 21:51:56 +00002663#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002667#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 if (ret == NULL)
2669 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002670 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671}
Larry Hastings2f936352014-08-05 14:04:04 +10002672#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673
Larry Hastings2f936352014-08-05 14:04:04 +10002674
2675/*[clinic input]
2676os.chdir
2677
2678 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2679
2680Change the current working directory to the specified path.
2681
2682path may always be specified as a string.
2683On some platforms, path may also be specified as an open file descriptor.
2684 If this functionality is unavailable, using it raises an exception.
2685[clinic start generated code]*/
2686
Larry Hastings2f936352014-08-05 14:04:04 +10002687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002688os_chdir_impl(PyObject *module, path_t *path)
2689/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002690{
2691 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692
2693 Py_BEGIN_ALLOW_THREADS
2694#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002695 /* on unix, success = 0, on windows, success = !0 */
2696 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697#else
2698#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002699 if (path->fd != -1)
2700 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701 else
2702#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002703 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704#endif
2705 Py_END_ALLOW_THREADS
2706
2707 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002708 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709 }
2710
Larry Hastings2f936352014-08-05 14:04:04 +10002711 Py_RETURN_NONE;
2712}
2713
2714
2715#ifdef HAVE_FCHDIR
2716/*[clinic input]
2717os.fchdir
2718
2719 fd: fildes
2720
2721Change to the directory of the given file descriptor.
2722
2723fd must be opened on a directory, not a file.
2724Equivalent to os.chdir(fd).
2725
2726[clinic start generated code]*/
2727
Fred Drake4d1e64b2002-04-15 19:40:07 +00002728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002729os_fchdir_impl(PyObject *module, int fd)
2730/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002731{
Larry Hastings2f936352014-08-05 14:04:04 +10002732 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002733}
2734#endif /* HAVE_FCHDIR */
2735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002736
Larry Hastings2f936352014-08-05 14:04:04 +10002737/*[clinic input]
2738os.chmod
2739
2740 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetrics08026b12018-11-02 17:56:25 +00002741 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002742 On some platforms, path may also be specified as an open file descriptor.
2743 If this functionality is unavailable, using it raises an exception.
2744
2745 mode: int
2746 Operating-system mode bitfield.
2747
2748 *
2749
2750 dir_fd : dir_fd(requires='fchmodat') = None
2751 If not None, it should be a file descriptor open to a directory,
2752 and path should be relative; path will then be relative to that
2753 directory.
2754
2755 follow_symlinks: bool = True
2756 If False, and the last element of the path is a symbolic link,
2757 chmod will modify the symbolic link itself instead of the file
2758 the link points to.
2759
2760Change the access permissions of a file.
2761
2762It is an error to use dir_fd or follow_symlinks when specifying path as
2763 an open file descriptor.
2764dir_fd and follow_symlinks may not be implemented on your platform.
2765 If they are unavailable, using them will raise a NotImplementedError.
2766
2767[clinic start generated code]*/
2768
Larry Hastings2f936352014-08-05 14:04:04 +10002769static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002770os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002771 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002772/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002773{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002775
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002776#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002779
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780#ifdef HAVE_FCHMODAT
2781 int fchmodat_nofollow_unsupported = 0;
2782#endif
2783
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2785 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002786 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787#endif
2788
2789#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002790 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002791 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002792 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 result = 0;
2794 else {
2795 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 attr &= ~FILE_ATTRIBUTE_READONLY;
2797 else
2798 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002799 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800 }
2801 Py_END_ALLOW_THREADS
2802
2803 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002804 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805 }
2806#else /* MS_WINDOWS */
2807 Py_BEGIN_ALLOW_THREADS
2808#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002809 if (path->fd != -1)
2810 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 else
2812#endif
2813#ifdef HAVE_LCHMOD
2814 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002815 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 else
2817#endif
2818#ifdef HAVE_FCHMODAT
2819 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2820 /*
2821 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2822 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002823 * and then says it isn't implemented yet.
2824 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 *
2826 * Once it is supported, os.chmod will automatically
2827 * support dir_fd and follow_symlinks=False. (Hopefully.)
2828 * Until then, we need to be careful what exception we raise.
2829 */
Larry Hastings2f936352014-08-05 14:04:04 +10002830 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2832 /*
2833 * But wait! We can't throw the exception without allowing threads,
2834 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2835 */
2836 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002837 result &&
2838 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2839 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 }
2841 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002842#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002843 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 Py_END_ALLOW_THREADS
2845
2846 if (result) {
2847#ifdef HAVE_FCHMODAT
2848 if (fchmodat_nofollow_unsupported) {
2849 if (dir_fd != DEFAULT_DIR_FD)
2850 dir_fd_and_follow_symlinks_invalid("chmod",
2851 dir_fd, follow_symlinks);
2852 else
2853 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002854 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 }
2856 else
2857#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002858 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 }
2860#endif
2861
Larry Hastings2f936352014-08-05 14:04:04 +10002862 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002863}
2864
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865
Christian Heimes4e30a842007-11-30 22:12:06 +00002866#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002867/*[clinic input]
2868os.fchmod
2869
2870 fd: int
2871 mode: int
2872
2873Change the access permissions of the file given by file descriptor fd.
2874
2875Equivalent to os.chmod(fd, mode).
2876[clinic start generated code]*/
2877
Larry Hastings2f936352014-08-05 14:04:04 +10002878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002879os_fchmod_impl(PyObject *module, int fd, int mode)
2880/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002881{
2882 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002883 int async_err = 0;
2884
2885 do {
2886 Py_BEGIN_ALLOW_THREADS
2887 res = fchmod(fd, mode);
2888 Py_END_ALLOW_THREADS
2889 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2890 if (res != 0)
2891 return (!async_err) ? posix_error() : NULL;
2892
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002894}
2895#endif /* HAVE_FCHMOD */
2896
Larry Hastings2f936352014-08-05 14:04:04 +10002897
Christian Heimes4e30a842007-11-30 22:12:06 +00002898#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002899/*[clinic input]
2900os.lchmod
2901
2902 path: path_t
2903 mode: int
2904
2905Change the access permissions of a file, without following symbolic links.
2906
2907If path is a symlink, this affects the link itself rather than the target.
2908Equivalent to chmod(path, mode, follow_symlinks=False)."
2909[clinic start generated code]*/
2910
Larry Hastings2f936352014-08-05 14:04:04 +10002911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002912os_lchmod_impl(PyObject *module, path_t *path, int mode)
2913/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002914{
Victor Stinner8c62be82010-05-06 00:08:46 +00002915 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002917 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002919 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002920 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002921 return NULL;
2922 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002923 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002924}
2925#endif /* HAVE_LCHMOD */
2926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002927
Thomas Wouterscf297e42007-02-23 15:07:44 +00002928#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002929/*[clinic input]
2930os.chflags
2931
2932 path: path_t
2933 flags: unsigned_long(bitwise=True)
2934 follow_symlinks: bool=True
2935
2936Set file flags.
2937
2938If follow_symlinks is False, and the last element of the path is a symbolic
2939 link, chflags will change flags on the symbolic link itself instead of the
2940 file the link points to.
2941follow_symlinks may not be implemented on your platform. If it is
2942unavailable, using it will raise a NotImplementedError.
2943
2944[clinic start generated code]*/
2945
Larry Hastings2f936352014-08-05 14:04:04 +10002946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002947os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002948 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002949/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002950{
2951 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002952
2953#ifndef HAVE_LCHFLAGS
2954 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002955 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956#endif
2957
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959#ifdef HAVE_LCHFLAGS
2960 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002961 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 else
2963#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002964 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002965 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966
Larry Hastings2f936352014-08-05 14:04:04 +10002967 if (result)
2968 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969
Larry Hastings2f936352014-08-05 14:04:04 +10002970 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002971}
2972#endif /* HAVE_CHFLAGS */
2973
Larry Hastings2f936352014-08-05 14:04:04 +10002974
Thomas Wouterscf297e42007-02-23 15:07:44 +00002975#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002976/*[clinic input]
2977os.lchflags
2978
2979 path: path_t
2980 flags: unsigned_long(bitwise=True)
2981
2982Set file flags.
2983
2984This function will not follow symbolic links.
2985Equivalent to chflags(path, flags, follow_symlinks=False).
2986[clinic start generated code]*/
2987
Larry Hastings2f936352014-08-05 14:04:04 +10002988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002989os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2990/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002991{
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002994 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002996 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002997 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002998 }
Victor Stinner292c8352012-10-30 02:17:38 +01002999 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003000}
3001#endif /* HAVE_LCHFLAGS */
3002
Larry Hastings2f936352014-08-05 14:04:04 +10003003
Martin v. Löwis244edc82001-10-04 22:44:26 +00003004#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003005/*[clinic input]
3006os.chroot
3007 path: path_t
3008
3009Change root directory to path.
3010
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_chroot_impl(PyObject *module, path_t *path)
3015/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
3017 int res;
3018 Py_BEGIN_ALLOW_THREADS
3019 res = chroot(path->narrow);
3020 Py_END_ALLOW_THREADS
3021 if (res < 0)
3022 return path_error(path);
3023 Py_RETURN_NONE;
3024}
3025#endif /* HAVE_CHROOT */
3026
Martin v. Löwis244edc82001-10-04 22:44:26 +00003027
Guido van Rossum21142a01999-01-08 21:05:37 +00003028#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003029/*[clinic input]
3030os.fsync
3031
3032 fd: fildes
3033
3034Force write of fd to disk.
3035[clinic start generated code]*/
3036
Larry Hastings2f936352014-08-05 14:04:04 +10003037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003038os_fsync_impl(PyObject *module, int fd)
3039/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003040{
3041 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003042}
3043#endif /* HAVE_FSYNC */
3044
Larry Hastings2f936352014-08-05 14:04:04 +10003045
Ross Lagerwall7807c352011-03-17 20:20:30 +02003046#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003047/*[clinic input]
3048os.sync
3049
3050Force write of everything to disk.
3051[clinic start generated code]*/
3052
Larry Hastings2f936352014-08-05 14:04:04 +10003053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003054os_sync_impl(PyObject *module)
3055/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003056{
3057 Py_BEGIN_ALLOW_THREADS
3058 sync();
3059 Py_END_ALLOW_THREADS
3060 Py_RETURN_NONE;
3061}
Larry Hastings2f936352014-08-05 14:04:04 +10003062#endif /* HAVE_SYNC */
3063
Ross Lagerwall7807c352011-03-17 20:20:30 +02003064
Guido van Rossum21142a01999-01-08 21:05:37 +00003065#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003066#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003067extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3068#endif
3069
Larry Hastings2f936352014-08-05 14:04:04 +10003070/*[clinic input]
3071os.fdatasync
3072
3073 fd: fildes
3074
3075Force write of fd to disk without forcing update of metadata.
3076[clinic start generated code]*/
3077
Larry Hastings2f936352014-08-05 14:04:04 +10003078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003079os_fdatasync_impl(PyObject *module, int fd)
3080/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003081{
3082 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003083}
3084#endif /* HAVE_FDATASYNC */
3085
3086
Fredrik Lundh10723342000-07-10 16:38:09 +00003087#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003088/*[clinic input]
3089os.chown
3090
3091 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetrics08026b12018-11-02 17:56:25 +00003092 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003093
3094 uid: uid_t
3095
3096 gid: gid_t
3097
3098 *
3099
3100 dir_fd : dir_fd(requires='fchownat') = None
3101 If not None, it should be a file descriptor open to a directory,
3102 and path should be relative; path will then be relative to that
3103 directory.
3104
3105 follow_symlinks: bool = True
3106 If False, and the last element of the path is a symbolic link,
3107 stat will examine the symbolic link itself instead of the file
3108 the link points to.
3109
3110Change the owner and group id of path to the numeric uid and gid.\
3111
3112path may always be specified as a string.
3113On some platforms, path may also be specified as an open file descriptor.
3114 If this functionality is unavailable, using it raises an exception.
3115If dir_fd is not None, it should be a file descriptor open to a directory,
3116 and path should be relative; path will then be relative to that directory.
3117If follow_symlinks is False, and the last element of the path is a symbolic
3118 link, chown will modify the symbolic link itself instead of the file the
3119 link points to.
3120It is an error to use dir_fd or follow_symlinks when specifying path as
3121 an open file descriptor.
3122dir_fd and follow_symlinks may not be implemented on your platform.
3123 If they are unavailable, using them will raise a NotImplementedError.
3124
3125[clinic start generated code]*/
3126
Larry Hastings2f936352014-08-05 14:04:04 +10003127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003128os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003129 int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00003130/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003131{
3132 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003133
3134#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3135 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003136 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003138 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3139 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141
3142#ifdef __APPLE__
3143 /*
3144 * This is for Mac OS X 10.3, which doesn't have lchown.
3145 * (But we still have an lchown symbol because of weak-linking.)
3146 * It doesn't have fchownat either. So there's no possibility
3147 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003148 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149 if ((!follow_symlinks) && (lchown == NULL)) {
3150 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003151 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152 }
3153#endif
3154
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003157 if (path->fd != -1)
3158 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159 else
3160#endif
3161#ifdef HAVE_LCHOWN
3162 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003163 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003164 else
3165#endif
3166#ifdef HAVE_FCHOWNAT
3167 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003168 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3170 else
3171#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003172 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174
Larry Hastings2f936352014-08-05 14:04:04 +10003175 if (result)
3176 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177
Larry Hastings2f936352014-08-05 14:04:04 +10003178 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003179}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003180#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003181
Larry Hastings2f936352014-08-05 14:04:04 +10003182
Christian Heimes4e30a842007-11-30 22:12:06 +00003183#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003184/*[clinic input]
3185os.fchown
3186
3187 fd: int
3188 uid: uid_t
3189 gid: gid_t
3190
3191Change the owner and group id of the file specified by file descriptor.
3192
3193Equivalent to os.chown(fd, uid, gid).
3194
3195[clinic start generated code]*/
3196
Larry Hastings2f936352014-08-05 14:04:04 +10003197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003198os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3199/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003200{
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003202 int async_err = 0;
3203
3204 do {
3205 Py_BEGIN_ALLOW_THREADS
3206 res = fchown(fd, uid, gid);
3207 Py_END_ALLOW_THREADS
3208 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3209 if (res != 0)
3210 return (!async_err) ? posix_error() : NULL;
3211
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003213}
3214#endif /* HAVE_FCHOWN */
3215
Larry Hastings2f936352014-08-05 14:04:04 +10003216
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003217#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003218/*[clinic input]
3219os.lchown
3220
3221 path : path_t
3222 uid: uid_t
3223 gid: gid_t
3224
3225Change the owner and group id of path to the numeric uid and gid.
3226
3227This function will not follow symbolic links.
3228Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3229[clinic start generated code]*/
3230
Larry Hastings2f936352014-08-05 14:04:04 +10003231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003232os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3233/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003234{
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003237 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003238 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003239 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003240 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003241 }
Larry Hastings2f936352014-08-05 14:04:04 +10003242 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003243}
3244#endif /* HAVE_LCHOWN */
3245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003246
Barry Warsaw53699e91996-12-10 23:23:01 +00003247static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003248posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003249{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003250 char *buf, *tmpbuf;
3251 char *cwd;
3252 const size_t chunk = 1024;
3253 size_t buflen = 0;
3254 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003255
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003256#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003258 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 wchar_t *wbuf2 = wbuf;
3260 PyObject *resobj;
3261 DWORD len;
3262 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003263 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 /* If the buffer is large enough, len does not include the
3265 terminating \0. If the buffer is too small, len includes
3266 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003267 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003268 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 if (wbuf2)
3270 len = GetCurrentDirectoryW(len, wbuf2);
3271 }
3272 Py_END_ALLOW_THREADS
3273 if (!wbuf2) {
3274 PyErr_NoMemory();
3275 return NULL;
3276 }
3277 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003278 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003279 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003280 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 }
3282 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003283 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003284 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 return resobj;
3286 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003287
3288 if (win32_warn_bytes_api())
3289 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003290#endif
3291
Victor Stinner4403d7d2015-04-25 00:16:10 +02003292 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003294 do {
3295 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003296#ifdef MS_WINDOWS
3297 if (buflen > INT_MAX) {
3298 PyErr_NoMemory();
3299 break;
3300 }
3301#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003302 tmpbuf = PyMem_RawRealloc(buf, buflen);
3303 if (tmpbuf == NULL)
3304 break;
3305
3306 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003307#ifdef MS_WINDOWS
3308 cwd = getcwd(buf, (int)buflen);
3309#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003310 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003311#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003312 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003314
3315 if (cwd == NULL) {
3316 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003317 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003318 }
3319
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003321 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3322 else
3323 obj = PyUnicode_DecodeFSDefault(buf);
3324 PyMem_RawFree(buf);
3325
3326 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003327}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003328
Larry Hastings2f936352014-08-05 14:04:04 +10003329
3330/*[clinic input]
3331os.getcwd
3332
3333Return a unicode string representing the current working directory.
3334[clinic start generated code]*/
3335
Larry Hastings2f936352014-08-05 14:04:04 +10003336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003337os_getcwd_impl(PyObject *module)
3338/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003339{
3340 return posix_getcwd(0);
3341}
3342
Larry Hastings2f936352014-08-05 14:04:04 +10003343
3344/*[clinic input]
3345os.getcwdb
3346
3347Return a bytes string representing the current working directory.
3348[clinic start generated code]*/
3349
Larry Hastings2f936352014-08-05 14:04:04 +10003350static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003351os_getcwdb_impl(PyObject *module)
3352/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003353{
3354 return posix_getcwd(1);
3355}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003356
Larry Hastings2f936352014-08-05 14:04:04 +10003357
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3359#define HAVE_LINK 1
3360#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
Guido van Rossumb6775db1994-08-01 11:34:53 +00003362#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003363/*[clinic input]
3364
3365os.link
3366
3367 src : path_t
3368 dst : path_t
3369 *
3370 src_dir_fd : dir_fd = None
3371 dst_dir_fd : dir_fd = None
3372 follow_symlinks: bool = True
3373
3374Create a hard link to a file.
3375
3376If either src_dir_fd or dst_dir_fd is not None, it should be a file
3377 descriptor open to a directory, and the respective path string (src or dst)
3378 should be relative; the path will then be relative to that directory.
3379If follow_symlinks is False, and the last element of src is a symbolic
3380 link, link will create a link to the symbolic link itself instead of the
3381 file the link points to.
3382src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3383 platform. If they are unavailable, using them will raise a
3384 NotImplementedError.
3385[clinic start generated code]*/
3386
Larry Hastings2f936352014-08-05 14:04:04 +10003387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003388os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003389 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003390/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003391{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003393 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394#else
3395 int result;
3396#endif
3397
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398#ifndef HAVE_LINKAT
3399 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3400 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003401 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402 }
3403#endif
3404
Steve Dowercc16be82016-09-08 10:35:16 -07003405#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003406 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 PyErr_SetString(PyExc_NotImplementedError,
3408 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003409 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410 }
Steve Dowercc16be82016-09-08 10:35:16 -07003411#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003412
Brian Curtin1b9df392010-11-24 20:24:31 +00003413#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003415 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003417
Larry Hastings2f936352014-08-05 14:04:04 +10003418 if (!result)
3419 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420#else
3421 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003422#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3424 (dst_dir_fd != DEFAULT_DIR_FD) ||
3425 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003426 result = linkat(src_dir_fd, src->narrow,
3427 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3429 else
Steve Dowercc16be82016-09-08 10:35:16 -07003430#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003431 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if (result)
3435 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003436#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437
Larry Hastings2f936352014-08-05 14:04:04 +10003438 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003439}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440#endif
3441
Brian Curtin1b9df392010-11-24 20:24:31 +00003442
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003443#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003444static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003446{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447 PyObject *v;
3448 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3449 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003450 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003452 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454
Steve Dowercc16be82016-09-08 10:35:16 -07003455 WIN32_FIND_DATAW wFileData;
3456 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003457
Steve Dowercc16be82016-09-08 10:35:16 -07003458 if (!path->wide) { /* Default arg: "." */
3459 po_wchars = L".";
3460 len = 1;
3461 } else {
3462 po_wchars = path->wide;
3463 len = wcslen(path->wide);
3464 }
3465 /* The +5 is so we can append "\\*.*\0" */
3466 wnamebuf = PyMem_New(wchar_t, len + 5);
3467 if (!wnamebuf) {
3468 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 }
Steve Dowercc16be82016-09-08 10:35:16 -07003471 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003473 wchar_t wch = wnamebuf[len-1];
3474 if (wch != SEP && wch != ALTSEP && wch != L':')
3475 wnamebuf[len++] = SEP;
3476 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 }
Steve Dowercc16be82016-09-08 10:35:16 -07003478 if ((list = PyList_New(0)) == NULL) {
3479 goto exit;
3480 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003481 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003482 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003483 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 if (hFindFile == INVALID_HANDLE_VALUE) {
3485 int error = GetLastError();
3486 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 goto exit;
3488 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003489 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 }
3492 do {
3493 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003494 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3495 wcscmp(wFileData.cFileName, L"..") != 0) {
3496 v = PyUnicode_FromWideChar(wFileData.cFileName,
3497 wcslen(wFileData.cFileName));
3498 if (path->narrow && v) {
3499 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3500 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_DECREF(list);
3503 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 break;
3505 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 Py_DECREF(list);
3509 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 break;
3511 }
3512 Py_DECREF(v);
3513 }
3514 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003515 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 Py_END_ALLOW_THREADS
3517 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3518 it got to the end of the directory. */
3519 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003521 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
3524 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003525
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526exit:
3527 if (hFindFile != INVALID_HANDLE_VALUE) {
3528 if (FindClose(hFindFile) == FALSE) {
3529 if (list != NULL) {
3530 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 }
3533 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003535 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003536
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003538} /* end of _listdir_windows_no_opendir */
3539
3540#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3541
3542static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003543_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003544{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003545 PyObject *v;
3546 DIR *dirp = NULL;
3547 struct dirent *ep;
3548 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003549#ifdef HAVE_FDOPENDIR
3550 int fd = -1;
3551#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003552
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003555 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003557 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003558 if (fd == -1)
3559 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560
Larry Hastingsfdaea062012-06-25 04:42:23 -07003561 return_str = 1;
3562
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_BEGIN_ALLOW_THREADS
3564 dirp = fdopendir(fd);
3565 Py_END_ALLOW_THREADS
3566 }
3567 else
3568#endif
3569 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003570 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003571 if (path->narrow) {
3572 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003573 /* only return bytes if they specified a bytes-like object */
3574 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003575 }
3576 else {
3577 name = ".";
3578 return_str = 1;
3579 }
3580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 Py_BEGIN_ALLOW_THREADS
3582 dirp = opendir(name);
3583 Py_END_ALLOW_THREADS
3584 }
3585
3586 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003587 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003588#ifdef HAVE_FDOPENDIR
3589 if (fd != -1) {
3590 Py_BEGIN_ALLOW_THREADS
3591 close(fd);
3592 Py_END_ALLOW_THREADS
3593 }
3594#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595 goto exit;
3596 }
3597 if ((list = PyList_New(0)) == NULL) {
3598 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 }
3600 for (;;) {
3601 errno = 0;
3602 Py_BEGIN_ALLOW_THREADS
3603 ep = readdir(dirp);
3604 Py_END_ALLOW_THREADS
3605 if (ep == NULL) {
3606 if (errno == 0) {
3607 break;
3608 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 }
3613 }
3614 if (ep->d_name[0] == '.' &&
3615 (NAMLEN(ep) == 1 ||
3616 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3617 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003618 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003619 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3620 else
3621 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 break;
3625 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 break;
3630 }
3631 Py_DECREF(v);
3632 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003633
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634exit:
3635 if (dirp != NULL) {
3636 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003637#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 if (fd > -1)
3639 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003640#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641 closedir(dirp);
3642 Py_END_ALLOW_THREADS
3643 }
3644
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003646} /* end of _posix_listdir */
3647#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003648
Larry Hastings2f936352014-08-05 14:04:04 +10003649
3650/*[clinic input]
3651os.listdir
3652
3653 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3654
3655Return a list containing the names of the files in the directory.
3656
BNMetrics08026b12018-11-02 17:56:25 +00003657path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003658 the filenames returned will also be bytes; in all other circumstances
3659 the filenames returned will be str.
3660If path is None, uses the path='.'.
3661On some platforms, path may also be specified as an open file descriptor;\
3662 the file descriptor must refer to a directory.
3663 If this functionality is unavailable, using it raises NotImplementedError.
3664
3665The list is in arbitrary order. It does not include the special
3666entries '.' and '..' even if they are present in the directory.
3667
3668
3669[clinic start generated code]*/
3670
Larry Hastings2f936352014-08-05 14:04:04 +10003671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003672os_listdir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +00003673/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003674{
3675#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3676 return _listdir_windows_no_opendir(path, NULL);
3677#else
3678 return _posix_listdir(path, NULL);
3679#endif
3680}
3681
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003682#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003683/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003684/*[clinic input]
3685os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003686
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003687 path: path_t
3688 /
3689
3690[clinic start generated code]*/
3691
3692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003693os__getfullpathname_impl(PyObject *module, path_t *path)
3694/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003695{
Steve Dowercc16be82016-09-08 10:35:16 -07003696 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3697 wchar_t *wtemp;
3698 DWORD result;
3699 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003700
Steve Dowercc16be82016-09-08 10:35:16 -07003701 result = GetFullPathNameW(path->wide,
3702 Py_ARRAY_LENGTH(woutbuf),
3703 woutbuf, &wtemp);
3704 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3705 woutbufp = PyMem_New(wchar_t, result);
3706 if (!woutbufp)
3707 return PyErr_NoMemory();
3708 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 }
Steve Dowercc16be82016-09-08 10:35:16 -07003710 if (result) {
3711 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3712 if (path->narrow)
3713 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3714 } else
3715 v = win32_error_object("GetFullPathNameW", path->object);
3716 if (woutbufp != woutbuf)
3717 PyMem_Free(woutbufp);
3718 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003719}
Brian Curtind40e6f72010-07-08 21:39:08 +00003720
Brian Curtind25aef52011-06-13 15:16:04 -05003721
Larry Hastings2f936352014-08-05 14:04:04 +10003722/*[clinic input]
3723os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003724
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003725 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003726 /
3727
3728A helper function for samepath on windows.
3729[clinic start generated code]*/
3730
Larry Hastings2f936352014-08-05 14:04:04 +10003731static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003732os__getfinalpathname_impl(PyObject *module, path_t *path)
3733/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003734{
3735 HANDLE hFile;
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003736 wchar_t buf[MAXPATHLEN], *target_path = buf;
3737 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003738 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003739 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003740
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003741 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003742 hFile = CreateFileW(
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003743 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003744 0, /* desired access */
3745 0, /* share mode */
3746 NULL, /* security attributes */
3747 OPEN_EXISTING,
3748 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3749 FILE_FLAG_BACKUP_SEMANTICS,
3750 NULL);
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003751 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003752
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003753 if (hFile == INVALID_HANDLE_VALUE) {
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003754 return win32_error_object("CreateFileW", path->object);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003755 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003756
3757 /* We have a good handle to the target, use it to determine the
3758 target path name. */
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003759 while (1) {
3760 Py_BEGIN_ALLOW_THREADS
3761 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3762 buf_size, VOLUME_NAME_DOS);
3763 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003764
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003765 if (!result_length) {
3766 result = win32_error_object("GetFinalPathNameByHandleW",
3767 path->object);
3768 goto cleanup;
3769 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003770
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003771 if (result_length < buf_size) {
3772 break;
3773 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003774
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003775 wchar_t *tmp;
3776 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3777 result_length * sizeof(*tmp));
3778 if (!tmp) {
3779 result = PyErr_NoMemory();
3780 goto cleanup;
3781 }
3782
3783 buf_size = result_length;
3784 target_path = tmp;
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003785 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003786
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003787 result = PyUnicode_FromWideChar(target_path, result_length);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003788 if (path->narrow)
3789 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003790
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003791cleanup:
3792 if (target_path != buf) {
3793 PyMem_Free(target_path);
3794 }
3795 CloseHandle(hFile);
3796 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003797}
Brian Curtin62857742010-09-06 17:07:27 +00003798
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003799/*[clinic input]
3800os._isdir
3801
3802 path: path_t
3803 /
3804
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003805Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003806[clinic start generated code]*/
3807
Brian Curtin9c669cc2011-06-08 18:17:18 -05003808static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003809os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003810/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003811{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003812 DWORD attributes;
3813
Steve Dowerb22a6772016-07-17 20:49:38 -07003814 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003815 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003816 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003817
Brian Curtin9c669cc2011-06-08 18:17:18 -05003818 if (attributes == INVALID_FILE_ATTRIBUTES)
3819 Py_RETURN_FALSE;
3820
Brian Curtin9c669cc2011-06-08 18:17:18 -05003821 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3822 Py_RETURN_TRUE;
3823 else
3824 Py_RETURN_FALSE;
3825}
Tim Golden6b528062013-08-01 12:44:00 +01003826
Tim Golden6b528062013-08-01 12:44:00 +01003827
Larry Hastings2f936352014-08-05 14:04:04 +10003828/*[clinic input]
3829os._getvolumepathname
3830
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003831 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003832
3833A helper function for ismount on Win32.
3834[clinic start generated code]*/
3835
Larry Hastings2f936352014-08-05 14:04:04 +10003836static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003837os__getvolumepathname_impl(PyObject *module, path_t *path)
3838/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003839{
3840 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003841 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003842 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003843 BOOL ret;
3844
Tim Golden6b528062013-08-01 12:44:00 +01003845 /* Volume path should be shorter than entire path */
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003846 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003847
Victor Stinner850a18e2017-10-24 16:53:32 -07003848 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003849 PyErr_SetString(PyExc_OverflowError, "path too long");
3850 return NULL;
3851 }
3852
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003853 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003854 if (mountpath == NULL)
3855 return PyErr_NoMemory();
3856
3857 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003858 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003859 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003860 Py_END_ALLOW_THREADS
3861
3862 if (!ret) {
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003863 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003864 goto exit;
3865 }
3866 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003867 if (path->narrow)
3868 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003869
3870exit:
3871 PyMem_Free(mountpath);
3872 return result;
3873}
Tim Golden6b528062013-08-01 12:44:00 +01003874
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003875#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003876
Larry Hastings2f936352014-08-05 14:04:04 +10003877
3878/*[clinic input]
3879os.mkdir
3880
3881 path : path_t
3882
3883 mode: int = 0o777
3884
3885 *
3886
3887 dir_fd : dir_fd(requires='mkdirat') = None
3888
3889# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3890
3891Create a directory.
3892
3893If dir_fd is not None, it should be a file descriptor open to a directory,
3894 and path should be relative; path will then be relative to that directory.
3895dir_fd may not be implemented on your platform.
3896 If it is unavailable, using it will raise a NotImplementedError.
3897
3898The mode argument is ignored on Windows.
3899[clinic start generated code]*/
3900
Larry Hastings2f936352014-08-05 14:04:04 +10003901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003902os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3903/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003904{
3905 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003906
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003907#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003909 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003911
Larry Hastings2f936352014-08-05 14:04:04 +10003912 if (!result)
3913 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003916#if HAVE_MKDIRAT
3917 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003918 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919 else
3920#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003921#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003922 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003923#else
Larry Hastings2f936352014-08-05 14:04:04 +10003924 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003925#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003927 if (result < 0)
3928 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003929#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003930 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003931}
3932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003933
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003934/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3935#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003936#include <sys/resource.h>
3937#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003938
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003939
3940#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003941/*[clinic input]
3942os.nice
3943
3944 increment: int
3945 /
3946
3947Add increment to the priority of process and return the new priority.
3948[clinic start generated code]*/
3949
Larry Hastings2f936352014-08-05 14:04:04 +10003950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003951os_nice_impl(PyObject *module, int increment)
3952/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003953{
3954 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003955
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 /* There are two flavours of 'nice': one that returns the new
3957 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003958 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003959 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003960
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 If we are of the nice family that returns the new priority, we
3962 need to clear errno before the call, and check if errno is filled
3963 before calling posix_error() on a returnvalue of -1, because the
3964 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003965
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 errno = 0;
3967 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003968#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003969 if (value == 0)
3970 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003971#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003972 if (value == -1 && errno != 0)
3973 /* either nice() or getpriority() returned an error */
3974 return posix_error();
3975 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003976}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003977#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003978
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003979
3980#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003981/*[clinic input]
3982os.getpriority
3983
3984 which: int
3985 who: int
3986
3987Return program scheduling priority.
3988[clinic start generated code]*/
3989
Larry Hastings2f936352014-08-05 14:04:04 +10003990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003991os_getpriority_impl(PyObject *module, int which, int who)
3992/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003993{
3994 int retval;
3995
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003996 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003997 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003998 if (errno != 0)
3999 return posix_error();
4000 return PyLong_FromLong((long)retval);
4001}
4002#endif /* HAVE_GETPRIORITY */
4003
4004
4005#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004006/*[clinic input]
4007os.setpriority
4008
4009 which: int
4010 who: int
4011 priority: int
4012
4013Set program scheduling priority.
4014[clinic start generated code]*/
4015
Larry Hastings2f936352014-08-05 14:04:04 +10004016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004017os_setpriority_impl(PyObject *module, int which, int who, int priority)
4018/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004019{
4020 int retval;
4021
4022 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004023 if (retval == -1)
4024 return posix_error();
4025 Py_RETURN_NONE;
4026}
4027#endif /* HAVE_SETPRIORITY */
4028
4029
Barry Warsaw53699e91996-12-10 23:23:01 +00004030static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004031internal_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 +00004032{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004033 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004034 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004035
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004036#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004037 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004038 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004039#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004041#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042
Larry Hastings9cf065c2012-06-22 16:30:09 -07004043 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4044 (dst_dir_fd != DEFAULT_DIR_FD);
4045#ifndef HAVE_RENAMEAT
4046 if (dir_fd_specified) {
4047 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004048 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049 }
4050#endif
4051
Larry Hastings9cf065c2012-06-22 16:30:09 -07004052#ifdef MS_WINDOWS
4053 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004054 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055 Py_END_ALLOW_THREADS
4056
Larry Hastings2f936352014-08-05 14:04:04 +10004057 if (!result)
4058 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059
4060#else
Steve Dowercc16be82016-09-08 10:35:16 -07004061 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4062 PyErr_Format(PyExc_ValueError,
4063 "%s: src and dst must be the same type", function_name);
4064 return NULL;
4065 }
4066
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 Py_BEGIN_ALLOW_THREADS
4068#ifdef HAVE_RENAMEAT
4069 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004070 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071 else
4072#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004073 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074 Py_END_ALLOW_THREADS
4075
Larry Hastings2f936352014-08-05 14:04:04 +10004076 if (result)
4077 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004079 Py_RETURN_NONE;
4080}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081
Larry Hastings2f936352014-08-05 14:04:04 +10004082
4083/*[clinic input]
4084os.rename
4085
4086 src : path_t
4087 dst : path_t
4088 *
4089 src_dir_fd : dir_fd = None
4090 dst_dir_fd : dir_fd = None
4091
4092Rename a file or directory.
4093
4094If either src_dir_fd or dst_dir_fd is not None, it should be a file
4095 descriptor open to a directory, and the respective path string (src or dst)
4096 should be relative; the path will then be relative to that directory.
4097src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4098 If they are unavailable, using them will raise a NotImplementedError.
4099[clinic start generated code]*/
4100
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004102os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004103 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004104/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004105{
Larry Hastings2f936352014-08-05 14:04:04 +10004106 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004107}
4108
Larry Hastings2f936352014-08-05 14:04:04 +10004109
4110/*[clinic input]
4111os.replace = os.rename
4112
4113Rename a file or directory, overwriting the destination.
4114
4115If either src_dir_fd or dst_dir_fd is not None, it should be a file
4116 descriptor open to a directory, and the respective path string (src or dst)
4117 should be relative; the path will then be relative to that directory.
4118src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4119 If they are unavailable, using them will raise a NotImplementedError."
4120[clinic start generated code]*/
4121
Larry Hastings2f936352014-08-05 14:04:04 +10004122static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004123os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4124 int dst_dir_fd)
4125/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004126{
4127 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4128}
4129
4130
4131/*[clinic input]
4132os.rmdir
4133
4134 path: path_t
4135 *
4136 dir_fd: dir_fd(requires='unlinkat') = None
4137
4138Remove a directory.
4139
4140If dir_fd is not None, it should be a file descriptor open to a directory,
4141 and path should be relative; path will then be relative to that directory.
4142dir_fd may not be implemented on your platform.
4143 If it is unavailable, using it will raise a NotImplementedError.
4144[clinic start generated code]*/
4145
Larry Hastings2f936352014-08-05 14:04:04 +10004146static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004147os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4148/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004149{
4150 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004151
4152 Py_BEGIN_ALLOW_THREADS
4153#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004154 /* Windows, success=1, UNIX, success=0 */
4155 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004156#else
4157#ifdef HAVE_UNLINKAT
4158 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004159 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004160 else
4161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004162 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004163#endif
4164 Py_END_ALLOW_THREADS
4165
Larry Hastings2f936352014-08-05 14:04:04 +10004166 if (result)
4167 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004168
Larry Hastings2f936352014-08-05 14:04:04 +10004169 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004170}
4171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004172
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004173#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004174#ifdef MS_WINDOWS
4175/*[clinic input]
4176os.system -> long
4177
4178 command: Py_UNICODE
4179
4180Execute the command in a subshell.
4181[clinic start generated code]*/
4182
Larry Hastings2f936352014-08-05 14:04:04 +10004183static long
Serhiy Storchaka45a7b762018-12-14 11:56:48 +02004184os_system_impl(PyObject *module, const Py_UNICODE *command)
4185/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004186{
4187 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004189 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004190 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004191 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004193 return result;
4194}
4195#else /* MS_WINDOWS */
4196/*[clinic input]
4197os.system -> long
4198
4199 command: FSConverter
4200
4201Execute the command in a subshell.
4202[clinic start generated code]*/
4203
Larry Hastings2f936352014-08-05 14:04:04 +10004204static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004205os_system_impl(PyObject *module, PyObject *command)
4206/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004207{
4208 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004209 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004210 Py_BEGIN_ALLOW_THREADS
4211 result = system(bytes);
4212 Py_END_ALLOW_THREADS
4213 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004214}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004215#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004216#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004218
Larry Hastings2f936352014-08-05 14:04:04 +10004219/*[clinic input]
4220os.umask
4221
4222 mask: int
4223 /
4224
4225Set the current numeric umask and return the previous umask.
4226[clinic start generated code]*/
4227
Larry Hastings2f936352014-08-05 14:04:04 +10004228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004229os_umask_impl(PyObject *module, int mask)
4230/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004231{
4232 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 if (i < 0)
4234 return posix_error();
4235 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004236}
4237
Brian Curtind40e6f72010-07-08 21:39:08 +00004238#ifdef MS_WINDOWS
4239
4240/* override the default DeleteFileW behavior so that directory
4241symlinks can be removed with this function, the same as with
4242Unix symlinks */
4243BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4244{
4245 WIN32_FILE_ATTRIBUTE_DATA info;
4246 WIN32_FIND_DATAW find_data;
4247 HANDLE find_data_handle;
4248 int is_directory = 0;
4249 int is_link = 0;
4250
4251 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4252 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004253
Brian Curtind40e6f72010-07-08 21:39:08 +00004254 /* Get WIN32_FIND_DATA structure for the path to determine if
4255 it is a symlink */
4256 if(is_directory &&
4257 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4258 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4259
4260 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004261 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4262 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4263 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4264 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004265 FindClose(find_data_handle);
4266 }
4267 }
4268 }
4269
4270 if (is_directory && is_link)
4271 return RemoveDirectoryW(lpFileName);
4272
4273 return DeleteFileW(lpFileName);
4274}
4275#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004277
Larry Hastings2f936352014-08-05 14:04:04 +10004278/*[clinic input]
4279os.unlink
4280
4281 path: path_t
4282 *
4283 dir_fd: dir_fd(requires='unlinkat')=None
4284
4285Remove a file (same as remove()).
4286
4287If dir_fd is not None, it should be a file descriptor open to a directory,
4288 and path should be relative; path will then be relative to that directory.
4289dir_fd may not be implemented on your platform.
4290 If it is unavailable, using it will raise a NotImplementedError.
4291
4292[clinic start generated code]*/
4293
Larry Hastings2f936352014-08-05 14:04:04 +10004294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004295os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4296/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004297{
4298 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004299
4300 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004301 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004302#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004303 /* Windows, success=1, UNIX, success=0 */
4304 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306#ifdef HAVE_UNLINKAT
4307 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004308 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004309 else
4310#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004311 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004313 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004314 Py_END_ALLOW_THREADS
4315
Larry Hastings2f936352014-08-05 14:04:04 +10004316 if (result)
4317 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318
Larry Hastings2f936352014-08-05 14:04:04 +10004319 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004320}
4321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004322
Larry Hastings2f936352014-08-05 14:04:04 +10004323/*[clinic input]
4324os.remove = os.unlink
4325
4326Remove a file (same as unlink()).
4327
4328If dir_fd is not None, it should be a file descriptor open to a directory,
4329 and path should be relative; path will then be relative to that directory.
4330dir_fd may not be implemented on your platform.
4331 If it is unavailable, using it will raise a NotImplementedError.
4332[clinic start generated code]*/
4333
Larry Hastings2f936352014-08-05 14:04:04 +10004334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004335os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4336/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004337{
4338 return os_unlink_impl(module, path, dir_fd);
4339}
4340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004341
Larry Hastings605a62d2012-06-24 04:33:36 -07004342static PyStructSequence_Field uname_result_fields[] = {
4343 {"sysname", "operating system name"},
4344 {"nodename", "name of machine on network (implementation-defined)"},
4345 {"release", "operating system release"},
4346 {"version", "operating system version"},
4347 {"machine", "hardware identifier"},
4348 {NULL}
4349};
4350
4351PyDoc_STRVAR(uname_result__doc__,
4352"uname_result: Result from os.uname().\n\n\
4353This object may be accessed either as a tuple of\n\
4354 (sysname, nodename, release, version, machine),\n\
4355or via the attributes sysname, nodename, release, version, and machine.\n\
4356\n\
4357See os.uname for more information.");
4358
4359static PyStructSequence_Desc uname_result_desc = {
4360 "uname_result", /* name */
4361 uname_result__doc__, /* doc */
4362 uname_result_fields,
4363 5
4364};
4365
4366static PyTypeObject UnameResultType;
4367
4368
4369#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004370/*[clinic input]
4371os.uname
4372
4373Return an object identifying the current operating system.
4374
4375The object behaves like a named tuple with the following fields:
4376 (sysname, nodename, release, version, machine)
4377
4378[clinic start generated code]*/
4379
Larry Hastings2f936352014-08-05 14:04:04 +10004380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004381os_uname_impl(PyObject *module)
4382/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004383{
Victor Stinner8c62be82010-05-06 00:08:46 +00004384 struct utsname u;
4385 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004386 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004387
Victor Stinner8c62be82010-05-06 00:08:46 +00004388 Py_BEGIN_ALLOW_THREADS
4389 res = uname(&u);
4390 Py_END_ALLOW_THREADS
4391 if (res < 0)
4392 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004393
4394 value = PyStructSequence_New(&UnameResultType);
4395 if (value == NULL)
4396 return NULL;
4397
4398#define SET(i, field) \
4399 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004400 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004401 if (!o) { \
4402 Py_DECREF(value); \
4403 return NULL; \
4404 } \
4405 PyStructSequence_SET_ITEM(value, i, o); \
4406 } \
4407
4408 SET(0, u.sysname);
4409 SET(1, u.nodename);
4410 SET(2, u.release);
4411 SET(3, u.version);
4412 SET(4, u.machine);
4413
4414#undef SET
4415
4416 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004417}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004418#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004419
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004420
Larry Hastings9cf065c2012-06-22 16:30:09 -07004421
4422typedef struct {
4423 int now;
4424 time_t atime_s;
4425 long atime_ns;
4426 time_t mtime_s;
4427 long mtime_ns;
4428} utime_t;
4429
4430/*
Victor Stinner484df002014-10-09 13:52:31 +02004431 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432 * they also intentionally leak the declaration of a pointer named "time"
4433 */
4434#define UTIME_TO_TIMESPEC \
4435 struct timespec ts[2]; \
4436 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004437 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438 time = NULL; \
4439 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004440 ts[0].tv_sec = ut->atime_s; \
4441 ts[0].tv_nsec = ut->atime_ns; \
4442 ts[1].tv_sec = ut->mtime_s; \
4443 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 time = ts; \
4445 } \
4446
4447#define UTIME_TO_TIMEVAL \
4448 struct timeval tv[2]; \
4449 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004450 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451 time = NULL; \
4452 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004453 tv[0].tv_sec = ut->atime_s; \
4454 tv[0].tv_usec = ut->atime_ns / 1000; \
4455 tv[1].tv_sec = ut->mtime_s; \
4456 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457 time = tv; \
4458 } \
4459
4460#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004461 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004462 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004463 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004464 time = NULL; \
4465 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004466 u.actime = ut->atime_s; \
4467 u.modtime = ut->mtime_s; \
4468 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 }
4470
4471#define UTIME_TO_TIME_T \
4472 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004473 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004474 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475 time = NULL; \
4476 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004477 timet[0] = ut->atime_s; \
4478 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004479 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480 } \
4481
4482
Victor Stinner528a9ab2015-09-03 21:30:26 +02004483#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484
4485static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004486utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487{
4488#ifdef HAVE_UTIMENSAT
4489 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4490 UTIME_TO_TIMESPEC;
4491 return utimensat(dir_fd, path, time, flags);
4492#elif defined(HAVE_FUTIMESAT)
4493 UTIME_TO_TIMEVAL;
4494 /*
4495 * follow_symlinks will never be false here;
4496 * we only allow !follow_symlinks and dir_fd together
4497 * if we have utimensat()
4498 */
4499 assert(follow_symlinks);
4500 return futimesat(dir_fd, path, time);
4501#endif
4502}
4503
Larry Hastings2f936352014-08-05 14:04:04 +10004504 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4505#else
4506 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004507#endif
4508
Victor Stinner528a9ab2015-09-03 21:30:26 +02004509#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510
4511static int
Victor Stinner484df002014-10-09 13:52:31 +02004512utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513{
4514#ifdef HAVE_FUTIMENS
4515 UTIME_TO_TIMESPEC;
4516 return futimens(fd, time);
4517#else
4518 UTIME_TO_TIMEVAL;
4519 return futimes(fd, time);
4520#endif
4521}
4522
Larry Hastings2f936352014-08-05 14:04:04 +10004523 #define PATH_UTIME_HAVE_FD 1
4524#else
4525 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526#endif
4527
Victor Stinner5ebae872015-09-22 01:29:33 +02004528#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4529# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4530#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531
Victor Stinner4552ced2015-09-21 22:37:15 +02004532#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533
4534static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004535utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536{
4537#ifdef HAVE_UTIMENSAT
4538 UTIME_TO_TIMESPEC;
4539 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4540#else
4541 UTIME_TO_TIMEVAL;
4542 return lutimes(path, time);
4543#endif
4544}
4545
4546#endif
4547
4548#ifndef MS_WINDOWS
4549
4550static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004551utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552{
4553#ifdef HAVE_UTIMENSAT
4554 UTIME_TO_TIMESPEC;
4555 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4556#elif defined(HAVE_UTIMES)
4557 UTIME_TO_TIMEVAL;
4558 return utimes(path, time);
4559#elif defined(HAVE_UTIME_H)
4560 UTIME_TO_UTIMBUF;
4561 return utime(path, time);
4562#else
4563 UTIME_TO_TIME_T;
4564 return utime(path, time);
4565#endif
4566}
4567
4568#endif
4569
Larry Hastings76ad59b2012-05-03 00:30:07 -07004570static int
4571split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4572{
4573 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004574 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004575 divmod = PyNumber_Divmod(py_long, billion);
4576 if (!divmod)
4577 goto exit;
Miss Islington (bot)329ea4e2018-09-12 12:46:30 -07004578 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4579 PyErr_Format(PyExc_TypeError,
4580 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4581 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4582 goto exit;
4583 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004584 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4585 if ((*s == -1) && PyErr_Occurred())
4586 goto exit;
4587 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004588 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004589 goto exit;
4590
4591 result = 1;
4592exit:
4593 Py_XDECREF(divmod);
4594 return result;
4595}
4596
Larry Hastings2f936352014-08-05 14:04:04 +10004597
4598/*[clinic input]
4599os.utime
4600
4601 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4602 times: object = NULL
4603 *
4604 ns: object = NULL
4605 dir_fd: dir_fd(requires='futimensat') = None
4606 follow_symlinks: bool=True
4607
Martin Panter0ff89092015-09-09 01:56:53 +00004608# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004609
4610Set the access and modified time of path.
4611
4612path may always be specified as a string.
4613On some platforms, path may also be specified as an open file descriptor.
4614 If this functionality is unavailable, using it raises an exception.
4615
4616If times is not None, it must be a tuple (atime, mtime);
4617 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004618If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004619 atime_ns and mtime_ns should be expressed as integer nanoseconds
4620 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004621If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004622Specifying tuples for both times and ns is an error.
4623
4624If dir_fd is not None, it should be a file descriptor open to a directory,
4625 and path should be relative; path will then be relative to that directory.
4626If follow_symlinks is False, and the last element of the path is a symbolic
4627 link, utime will modify the symbolic link itself instead of the file the
4628 link points to.
4629It is an error to use dir_fd or follow_symlinks when specifying path
4630 as an open file descriptor.
4631dir_fd and follow_symlinks may not be available on your platform.
4632 If they are unavailable, using them will raise a NotImplementedError.
4633
4634[clinic start generated code]*/
4635
Larry Hastings2f936352014-08-05 14:04:04 +10004636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004637os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4638 int dir_fd, int follow_symlinks)
4639/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004640{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641#ifdef MS_WINDOWS
4642 HANDLE hFile;
4643 FILETIME atime, mtime;
4644#else
4645 int result;
4646#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004647
Larry Hastings2f936352014-08-05 14:04:04 +10004648 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004649
Christian Heimesb3c87242013-08-01 00:08:16 +02004650 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004651
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 if (times && (times != Py_None) && ns) {
4653 PyErr_SetString(PyExc_ValueError,
4654 "utime: you may specify either 'times'"
4655 " or 'ns' but not both");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004656 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004657 }
4658
4659 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004660 time_t a_sec, m_sec;
4661 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004662 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 PyErr_SetString(PyExc_TypeError,
4664 "utime: 'times' must be either"
4665 " a tuple of two ints or None");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004666 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004669 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004670 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004671 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004672 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004673 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004674 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004675 utime.atime_s = a_sec;
4676 utime.atime_ns = a_nsec;
4677 utime.mtime_s = m_sec;
4678 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004679 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 PyErr_SetString(PyExc_TypeError,
4683 "utime: 'ns' must be a tuple of two ints");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004684 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004685 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004687 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004689 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 &utime.mtime_s, &utime.mtime_ns)) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004691 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004692 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 }
4694 else {
4695 /* times and ns are both None/unspecified. use "now". */
4696 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697 }
4698
Victor Stinner4552ced2015-09-21 22:37:15 +02004699#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700 if (follow_symlinks_specified("utime", follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004701 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004703
Larry Hastings2f936352014-08-05 14:04:04 +10004704 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4705 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4706 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004707 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004708
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709#if !defined(HAVE_UTIMENSAT)
4710 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004711 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 "utime: cannot use dir_fd and follow_symlinks "
4713 "together on this platform");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004714 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 }
4716#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004717
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004718#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004720 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4721 NULL, OPEN_EXISTING,
4722 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004723 Py_END_ALLOW_THREADS
4724 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004725 path_error(path);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004726 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004727 }
4728
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004730 GetSystemTimeAsFileTime(&mtime);
4731 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004732 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004734 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4735 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 }
4737 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4738 /* Avoid putting the file name into the error here,
4739 as that may confuse the user into believing that
4740 something is wrong with the file, when it also
4741 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004742 PyErr_SetFromWindowsErr(0);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004743 CloseHandle(hFile);
4744 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 }
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004746 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004747#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004749
Victor Stinner4552ced2015-09-21 22:37:15 +02004750#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004752 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004754#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755
Victor Stinner528a9ab2015-09-03 21:30:26 +02004756#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004758 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 else
4760#endif
4761
Victor Stinner528a9ab2015-09-03 21:30:26 +02004762#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004763 if (path->fd != -1)
4764 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 else
4766#endif
4767
Larry Hastings2f936352014-08-05 14:04:04 +10004768 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769
4770 Py_END_ALLOW_THREADS
4771
4772 if (result < 0) {
4773 /* see previous comment about not putting filename in error here */
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004774 posix_error();
4775 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004778#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004780 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004781}
4782
Guido van Rossum3b066191991-06-04 19:40:25 +00004783/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004784
Larry Hastings2f936352014-08-05 14:04:04 +10004785
4786/*[clinic input]
4787os._exit
4788
4789 status: int
4790
4791Exit to the system with specified status, without normal exit processing.
4792[clinic start generated code]*/
4793
Larry Hastings2f936352014-08-05 14:04:04 +10004794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004795os__exit_impl(PyObject *module, int status)
4796/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004797{
4798 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004800}
4801
Steve Dowercc16be82016-09-08 10:35:16 -07004802#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4803#define EXECV_CHAR wchar_t
4804#else
4805#define EXECV_CHAR char
4806#endif
4807
Martin v. Löwis114619e2002-10-07 06:44:21 +00004808#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4809static void
Steve Dowercc16be82016-09-08 10:35:16 -07004810free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004811{
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 Py_ssize_t i;
4813 for (i = 0; i < count; i++)
4814 PyMem_Free(array[i]);
4815 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004816}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004817
Berker Peksag81816462016-09-15 20:19:47 +03004818static int
4819fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004820{
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004822 PyObject *ub;
4823 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004824#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004825 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004826 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004827 *out = PyUnicode_AsWideCharString(ub, &size);
4828 if (*out)
4829 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004830#else
Berker Peksag81816462016-09-15 20:19:47 +03004831 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004833 size = PyBytes_GET_SIZE(ub);
4834 *out = PyMem_Malloc(size + 1);
4835 if (*out) {
4836 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4837 result = 1;
4838 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004839 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004840#endif
Berker Peksag81816462016-09-15 20:19:47 +03004841 Py_DECREF(ub);
4842 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004843}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004844#endif
4845
Ross Lagerwall7807c352011-03-17 20:20:30 +02004846#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004847static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004848parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4849{
Victor Stinner8c62be82010-05-06 00:08:46 +00004850 Py_ssize_t i, pos, envc;
4851 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004852 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004853 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004854
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 i = PyMapping_Size(env);
4856 if (i < 0)
4857 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004858 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 if (envlist == NULL) {
4860 PyErr_NoMemory();
4861 return NULL;
4862 }
4863 envc = 0;
4864 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004865 if (!keys)
4866 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004868 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 goto error;
4870 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4871 PyErr_Format(PyExc_TypeError,
4872 "env.keys() or env.values() is not a list");
4873 goto error;
4874 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004875
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 for (pos = 0; pos < i; pos++) {
4877 key = PyList_GetItem(keys, pos);
4878 val = PyList_GetItem(vals, pos);
4879 if (!key || !val)
4880 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004881
Berker Peksag81816462016-09-15 20:19:47 +03004882#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4883 if (!PyUnicode_FSDecoder(key, &key2))
4884 goto error;
4885 if (!PyUnicode_FSDecoder(val, &val2)) {
4886 Py_DECREF(key2);
4887 goto error;
4888 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004889 /* Search from index 1 because on Windows starting '=' is allowed for
4890 defining hidden environment variables. */
4891 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4892 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4893 {
4894 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004895 Py_DECREF(key2);
4896 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004897 goto error;
4898 }
Berker Peksag81816462016-09-15 20:19:47 +03004899 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4900#else
4901 if (!PyUnicode_FSConverter(key, &key2))
4902 goto error;
4903 if (!PyUnicode_FSConverter(val, &val2)) {
4904 Py_DECREF(key2);
4905 goto error;
4906 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004907 if (PyBytes_GET_SIZE(key2) == 0 ||
4908 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4909 {
4910 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004911 Py_DECREF(key2);
4912 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004913 goto error;
4914 }
Berker Peksag81816462016-09-15 20:19:47 +03004915 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4916 PyBytes_AS_STRING(val2));
4917#endif
4918 Py_DECREF(key2);
4919 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004920 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004922
4923 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4924 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 goto error;
4926 }
Berker Peksag81816462016-09-15 20:19:47 +03004927
Steve Dowercc16be82016-09-08 10:35:16 -07004928 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 }
4930 Py_DECREF(vals);
4931 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004932
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 envlist[envc] = 0;
4934 *envc_ptr = envc;
4935 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004936
4937error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 Py_XDECREF(keys);
4939 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004940 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004941 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004942}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004943
Steve Dowercc16be82016-09-08 10:35:16 -07004944static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004945parse_arglist(PyObject* argv, Py_ssize_t *argc)
4946{
4947 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004948 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949 if (argvlist == NULL) {
4950 PyErr_NoMemory();
4951 return NULL;
4952 }
4953 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004954 PyObject* item = PySequence_ITEM(argv, i);
4955 if (item == NULL)
4956 goto fail;
4957 if (!fsconvert_strdup(item, &argvlist[i])) {
4958 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004959 goto fail;
4960 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004961 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 }
4963 argvlist[*argc] = NULL;
4964 return argvlist;
4965fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004966 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004967 free_string_array(argvlist, *argc);
4968 return NULL;
4969}
Steve Dowercc16be82016-09-08 10:35:16 -07004970
Ross Lagerwall7807c352011-03-17 20:20:30 +02004971#endif
4972
Larry Hastings2f936352014-08-05 14:04:04 +10004973
Ross Lagerwall7807c352011-03-17 20:20:30 +02004974#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004975/*[clinic input]
4976os.execv
4977
Steve Dowercc16be82016-09-08 10:35:16 -07004978 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004979 Path of executable file.
4980 argv: object
4981 Tuple or list of strings.
4982 /
4983
4984Execute an executable path with arguments, replacing current process.
4985[clinic start generated code]*/
4986
Larry Hastings2f936352014-08-05 14:04:04 +10004987static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004988os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4989/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004990{
Steve Dowercc16be82016-09-08 10:35:16 -07004991 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004992 Py_ssize_t argc;
4993
4994 /* execv has two arguments: (path, argv), where
4995 argv is a list or tuple of strings. */
4996
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4998 PyErr_SetString(PyExc_TypeError,
4999 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005000 return NULL;
5001 }
5002 argc = PySequence_Size(argv);
5003 if (argc < 1) {
5004 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005 return NULL;
5006 }
5007
5008 argvlist = parse_arglist(argv, &argc);
5009 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005010 return NULL;
5011 }
Steve Dowerbce26262016-11-19 19:17:26 -08005012 if (!argvlist[0][0]) {
5013 PyErr_SetString(PyExc_ValueError,
5014 "execv() arg 2 first element cannot be empty");
5015 free_string_array(argvlist, argc);
5016 return NULL;
5017 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018
Steve Dowerbce26262016-11-19 19:17:26 -08005019 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005020#ifdef HAVE_WEXECV
5021 _wexecv(path->wide, argvlist);
5022#else
5023 execv(path->narrow, argvlist);
5024#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005025 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005026
5027 /* If we get here it's definitely an error */
5028
5029 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030 return posix_error();
5031}
5032
Larry Hastings2f936352014-08-05 14:04:04 +10005033
5034/*[clinic input]
5035os.execve
5036
5037 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5038 Path of executable file.
5039 argv: object
5040 Tuple or list of strings.
5041 env: object
5042 Dictionary of strings mapping to strings.
5043
5044Execute an executable path with arguments, replacing current process.
5045[clinic start generated code]*/
5046
Larry Hastings2f936352014-08-05 14:04:04 +10005047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005048os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5049/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005050{
Steve Dowercc16be82016-09-08 10:35:16 -07005051 EXECV_CHAR **argvlist = NULL;
5052 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005054
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 /* execve has three arguments: (path, argv, env), where
5056 argv is a list or tuple of strings and env is a dictionary
5057 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005058
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005061 "execve: argv must be a tuple or list");
5062 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005064 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005065 if (argc < 1) {
5066 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5067 return NULL;
5068 }
5069
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 if (!PyMapping_Check(env)) {
5071 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005072 "execve: environment must be a mapping object");
5073 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005075
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005078 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 }
Steve Dowerbce26262016-11-19 19:17:26 -08005080 if (!argvlist[0][0]) {
5081 PyErr_SetString(PyExc_ValueError,
5082 "execve: argv first element cannot be empty");
5083 goto fail;
5084 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005085
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 envlist = parse_envlist(env, &envc);
5087 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005088 goto fail;
5089
Steve Dowerbce26262016-11-19 19:17:26 -08005090 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005091#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005092 if (path->fd > -1)
5093 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005094 else
5095#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005096#ifdef HAVE_WEXECV
5097 _wexecve(path->wide, argvlist, envlist);
5098#else
Larry Hastings2f936352014-08-05 14:04:04 +10005099 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005100#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005101 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005102
5103 /* If we get here it's definitely an error */
5104
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07005105 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005106
Steve Dowercc16be82016-09-08 10:35:16 -07005107 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005109 if (argvlist)
5110 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 return NULL;
5112}
Steve Dowercc16be82016-09-08 10:35:16 -07005113
Larry Hastings9cf065c2012-06-22 16:30:09 -07005114#endif /* HAVE_EXECV */
5115
Steve Dowercc16be82016-09-08 10:35:16 -07005116#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005117/*[clinic input]
5118os.spawnv
5119
5120 mode: int
5121 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005122 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005123 Path of executable file.
5124 argv: object
5125 Tuple or list of strings.
5126 /
5127
5128Execute the program specified by path in a new process.
5129[clinic start generated code]*/
5130
Larry Hastings2f936352014-08-05 14:04:04 +10005131static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005132os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5133/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005134{
Steve Dowercc16be82016-09-08 10:35:16 -07005135 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005136 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005138 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005140
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 /* spawnv has three arguments: (mode, path, argv), where
5142 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005143
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 if (PyList_Check(argv)) {
5145 argc = PyList_Size(argv);
5146 getitem = PyList_GetItem;
5147 }
5148 else if (PyTuple_Check(argv)) {
5149 argc = PyTuple_Size(argv);
5150 getitem = PyTuple_GetItem;
5151 }
5152 else {
5153 PyErr_SetString(PyExc_TypeError,
5154 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 return NULL;
5156 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005157 if (argc == 0) {
5158 PyErr_SetString(PyExc_ValueError,
5159 "spawnv() arg 2 cannot be empty");
5160 return NULL;
5161 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005162
Steve Dowercc16be82016-09-08 10:35:16 -07005163 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 return PyErr_NoMemory();
5166 }
5167 for (i = 0; i < argc; i++) {
5168 if (!fsconvert_strdup((*getitem)(argv, i),
5169 &argvlist[i])) {
5170 free_string_array(argvlist, i);
5171 PyErr_SetString(
5172 PyExc_TypeError,
5173 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 return NULL;
5175 }
Steve Dower93ff8722016-11-19 19:03:54 -08005176 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005177 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005178 PyErr_SetString(
5179 PyExc_ValueError,
5180 "spawnv() arg 2 first element cannot be empty");
5181 return NULL;
5182 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 }
5184 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005185
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 if (mode == _OLD_P_OVERLAY)
5187 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005188
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005190 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005191#ifdef HAVE_WSPAWNV
5192 spawnval = _wspawnv(mode, path->wide, argvlist);
5193#else
5194 spawnval = _spawnv(mode, path->narrow, argvlist);
5195#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005196 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005198
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005200
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 if (spawnval == -1)
5202 return posix_error();
5203 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005204 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005205}
5206
Larry Hastings2f936352014-08-05 14:04:04 +10005207/*[clinic input]
5208os.spawnve
5209
5210 mode: int
5211 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005212 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005213 Path of executable file.
5214 argv: object
5215 Tuple or list of strings.
5216 env: object
5217 Dictionary of strings mapping to strings.
5218 /
5219
5220Execute the program specified by path in a new process.
5221[clinic start generated code]*/
5222
Larry Hastings2f936352014-08-05 14:04:04 +10005223static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005224os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005225 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005226/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005227{
Steve Dowercc16be82016-09-08 10:35:16 -07005228 EXECV_CHAR **argvlist;
5229 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005231 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005232 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005234 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005235
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 /* spawnve has four arguments: (mode, path, argv, env), where
5237 argv is a list or tuple of strings and env is a dictionary
5238 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005239
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 if (PyList_Check(argv)) {
5241 argc = PyList_Size(argv);
5242 getitem = PyList_GetItem;
5243 }
5244 else if (PyTuple_Check(argv)) {
5245 argc = PyTuple_Size(argv);
5246 getitem = PyTuple_GetItem;
5247 }
5248 else {
5249 PyErr_SetString(PyExc_TypeError,
5250 "spawnve() arg 2 must be a tuple or list");
5251 goto fail_0;
5252 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005253 if (argc == 0) {
5254 PyErr_SetString(PyExc_ValueError,
5255 "spawnve() arg 2 cannot be empty");
5256 goto fail_0;
5257 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 if (!PyMapping_Check(env)) {
5259 PyErr_SetString(PyExc_TypeError,
5260 "spawnve() arg 3 must be a mapping object");
5261 goto fail_0;
5262 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005263
Steve Dowercc16be82016-09-08 10:35:16 -07005264 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 if (argvlist == NULL) {
5266 PyErr_NoMemory();
5267 goto fail_0;
5268 }
5269 for (i = 0; i < argc; i++) {
5270 if (!fsconvert_strdup((*getitem)(argv, i),
5271 &argvlist[i]))
5272 {
5273 lastarg = i;
5274 goto fail_1;
5275 }
Steve Dowerbce26262016-11-19 19:17:26 -08005276 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005277 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005278 PyErr_SetString(
5279 PyExc_ValueError,
5280 "spawnv() arg 2 first element cannot be empty");
5281 goto fail_1;
5282 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 }
5284 lastarg = argc;
5285 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005286
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 envlist = parse_envlist(env, &envc);
5288 if (envlist == NULL)
5289 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 if (mode == _OLD_P_OVERLAY)
5292 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005295 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005296#ifdef HAVE_WSPAWNV
5297 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5298#else
5299 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5300#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005301 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 if (spawnval == -1)
5305 (void) posix_error();
5306 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005307 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005308
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 while (--envc >= 0)
5310 PyMem_DEL(envlist[envc]);
5311 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005312 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005313 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005314 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005316}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005317
Guido van Rossuma1065681999-01-25 23:20:23 +00005318#endif /* HAVE_SPAWNV */
5319
5320
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005321#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005322
5323/* Helper function to validate arguments.
5324 Returns 0 on success. non-zero on failure with a TypeError raised.
5325 If obj is non-NULL it must be callable. */
5326static int
5327check_null_or_callable(PyObject *obj, const char* obj_name)
5328{
5329 if (obj && !PyCallable_Check(obj)) {
5330 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5331 obj_name, Py_TYPE(obj)->tp_name);
5332 return -1;
5333 }
5334 return 0;
5335}
5336
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005337/*[clinic input]
5338os.register_at_fork
5339
Gregory P. Smith163468a2017-05-29 10:03:41 -07005340 *
5341 before: object=NULL
5342 A callable to be called in the parent before the fork() syscall.
5343 after_in_child: object=NULL
5344 A callable to be called in the child after fork().
5345 after_in_parent: object=NULL
5346 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005347
Gregory P. Smith163468a2017-05-29 10:03:41 -07005348Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005349
Gregory P. Smith163468a2017-05-29 10:03:41 -07005350'before' callbacks are called in reverse order.
5351'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005352
5353[clinic start generated code]*/
5354
5355static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005356os_register_at_fork_impl(PyObject *module, PyObject *before,
5357 PyObject *after_in_child, PyObject *after_in_parent)
5358/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005359{
5360 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005361
Gregory P. Smith163468a2017-05-29 10:03:41 -07005362 if (!before && !after_in_child && !after_in_parent) {
5363 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5364 return NULL;
5365 }
5366 if (check_null_or_callable(before, "before") ||
5367 check_null_or_callable(after_in_child, "after_in_child") ||
5368 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005369 return NULL;
5370 }
5371 interp = PyThreadState_Get()->interp;
5372
Gregory P. Smith163468a2017-05-29 10:03:41 -07005373 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005374 return NULL;
5375 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005376 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005377 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005378 }
5379 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5380 return NULL;
5381 }
5382 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005383}
5384#endif /* HAVE_FORK */
5385
5386
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005387#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005388/*[clinic input]
5389os.fork1
5390
5391Fork a child process with a single multiplexed (i.e., not bound) thread.
5392
5393Return 0 to child process and PID of child to parent process.
5394[clinic start generated code]*/
5395
Larry Hastings2f936352014-08-05 14:04:04 +10005396static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005397os_fork1_impl(PyObject *module)
5398/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005399{
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005401
5402 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 pid = fork1();
5404 if (pid == 0) {
5405 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005406 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 } else {
5408 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005409 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 }
5411 if (pid == -1)
5412 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005414}
Larry Hastings2f936352014-08-05 14:04:04 +10005415#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005416
5417
Guido van Rossumad0ee831995-03-01 10:34:45 +00005418#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005419/*[clinic input]
5420os.fork
5421
5422Fork a child process.
5423
5424Return 0 to child process and PID of child to parent process.
5425[clinic start generated code]*/
5426
Larry Hastings2f936352014-08-05 14:04:04 +10005427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005428os_fork_impl(PyObject *module)
5429/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005430{
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005432
5433 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005434 pid = fork();
5435 if (pid == 0) {
5436 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005437 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 } else {
5439 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005440 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 }
5442 if (pid == -1)
5443 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005445}
Larry Hastings2f936352014-08-05 14:04:04 +10005446#endif /* HAVE_FORK */
5447
Guido van Rossum85e3b011991-06-03 12:42:10 +00005448
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005449#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005450#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005451/*[clinic input]
5452os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005453
Larry Hastings2f936352014-08-05 14:04:04 +10005454 policy: int
5455
5456Get the maximum scheduling priority for policy.
5457[clinic start generated code]*/
5458
Larry Hastings2f936352014-08-05 14:04:04 +10005459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005460os_sched_get_priority_max_impl(PyObject *module, int policy)
5461/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005462{
5463 int max;
5464
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005465 max = sched_get_priority_max(policy);
5466 if (max < 0)
5467 return posix_error();
5468 return PyLong_FromLong(max);
5469}
5470
Larry Hastings2f936352014-08-05 14:04:04 +10005471
5472/*[clinic input]
5473os.sched_get_priority_min
5474
5475 policy: int
5476
5477Get the minimum scheduling priority for policy.
5478[clinic start generated code]*/
5479
Larry Hastings2f936352014-08-05 14:04:04 +10005480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005481os_sched_get_priority_min_impl(PyObject *module, int policy)
5482/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005483{
5484 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005485 if (min < 0)
5486 return posix_error();
5487 return PyLong_FromLong(min);
5488}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005489#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5490
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005491
Larry Hastings2f936352014-08-05 14:04:04 +10005492#ifdef HAVE_SCHED_SETSCHEDULER
5493/*[clinic input]
5494os.sched_getscheduler
5495 pid: pid_t
5496 /
5497
5498Get the scheduling policy for the process identifiedy by pid.
5499
5500Passing 0 for pid returns the scheduling policy for the calling process.
5501[clinic start generated code]*/
5502
Larry Hastings2f936352014-08-05 14:04:04 +10005503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005504os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5505/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005506{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005507 int policy;
5508
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005509 policy = sched_getscheduler(pid);
5510 if (policy < 0)
5511 return posix_error();
5512 return PyLong_FromLong(policy);
5513}
Larry Hastings2f936352014-08-05 14:04:04 +10005514#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005515
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005516
5517#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005518/*[clinic input]
5519class os.sched_param "PyObject *" "&SchedParamType"
5520
5521@classmethod
5522os.sched_param.__new__
5523
5524 sched_priority: object
5525 A scheduling parameter.
5526
5527Current has only one field: sched_priority");
5528[clinic start generated code]*/
5529
Larry Hastings2f936352014-08-05 14:04:04 +10005530static PyObject *
5531os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005532/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005533{
5534 PyObject *res;
5535
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005536 res = PyStructSequence_New(type);
5537 if (!res)
5538 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005539 Py_INCREF(sched_priority);
5540 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005541 return res;
5542}
5543
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005544
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005545PyDoc_VAR(os_sched_param__doc__);
5546
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547static PyStructSequence_Field sched_param_fields[] = {
5548 {"sched_priority", "the scheduling priority"},
5549 {0}
5550};
5551
5552static PyStructSequence_Desc sched_param_desc = {
5553 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005554 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005555 sched_param_fields,
5556 1
5557};
5558
5559static int
5560convert_sched_param(PyObject *param, struct sched_param *res)
5561{
5562 long priority;
5563
5564 if (Py_TYPE(param) != &SchedParamType) {
5565 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5566 return 0;
5567 }
5568 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5569 if (priority == -1 && PyErr_Occurred())
5570 return 0;
5571 if (priority > INT_MAX || priority < INT_MIN) {
5572 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5573 return 0;
5574 }
5575 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5576 return 1;
5577}
Larry Hastings2f936352014-08-05 14:04:04 +10005578#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005580
5581#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005582/*[clinic input]
5583os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005584
Larry Hastings2f936352014-08-05 14:04:04 +10005585 pid: pid_t
5586 policy: int
5587 param: sched_param
5588 /
5589
5590Set the scheduling policy for the process identified by pid.
5591
5592If pid is 0, the calling process is changed.
5593param is an instance of sched_param.
5594[clinic start generated code]*/
5595
Larry Hastings2f936352014-08-05 14:04:04 +10005596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005597os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005598 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005599/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005600{
Jesus Cea9c822272011-09-10 01:40:52 +02005601 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005602 ** sched_setscheduler() returns 0 in Linux, but the previous
5603 ** scheduling policy under Solaris/Illumos, and others.
5604 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005605 */
Larry Hastings2f936352014-08-05 14:04:04 +10005606 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005607 return posix_error();
5608 Py_RETURN_NONE;
5609}
Larry Hastings2f936352014-08-05 14:04:04 +10005610#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005611
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005612
5613#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005614/*[clinic input]
5615os.sched_getparam
5616 pid: pid_t
5617 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005618
Larry Hastings2f936352014-08-05 14:04:04 +10005619Returns scheduling parameters for the process identified by pid.
5620
5621If pid is 0, returns parameters for the calling process.
5622Return value is an instance of sched_param.
5623[clinic start generated code]*/
5624
Larry Hastings2f936352014-08-05 14:04:04 +10005625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005626os_sched_getparam_impl(PyObject *module, pid_t pid)
5627/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005628{
5629 struct sched_param param;
5630 PyObject *result;
5631 PyObject *priority;
5632
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005633 if (sched_getparam(pid, &param))
5634 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005635 result = PyStructSequence_New(&SchedParamType);
5636 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637 return NULL;
5638 priority = PyLong_FromLong(param.sched_priority);
5639 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005640 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005641 return NULL;
5642 }
Larry Hastings2f936352014-08-05 14:04:04 +10005643 PyStructSequence_SET_ITEM(result, 0, priority);
5644 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005645}
5646
Larry Hastings2f936352014-08-05 14:04:04 +10005647
5648/*[clinic input]
5649os.sched_setparam
5650 pid: pid_t
5651 param: sched_param
5652 /
5653
5654Set scheduling parameters for the process identified by pid.
5655
5656If pid is 0, sets parameters for the calling process.
5657param should be an instance of sched_param.
5658[clinic start generated code]*/
5659
Larry Hastings2f936352014-08-05 14:04:04 +10005660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005661os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005662 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005663/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005664{
5665 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005666 return posix_error();
5667 Py_RETURN_NONE;
5668}
Larry Hastings2f936352014-08-05 14:04:04 +10005669#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005670
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005671
5672#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005673/*[clinic input]
5674os.sched_rr_get_interval -> double
5675 pid: pid_t
5676 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005677
Larry Hastings2f936352014-08-05 14:04:04 +10005678Return the round-robin quantum for the process identified by pid, in seconds.
5679
5680Value returned is a float.
5681[clinic start generated code]*/
5682
Larry Hastings2f936352014-08-05 14:04:04 +10005683static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005684os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5685/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005686{
5687 struct timespec interval;
5688 if (sched_rr_get_interval(pid, &interval)) {
5689 posix_error();
5690 return -1.0;
5691 }
5692 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5693}
5694#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005695
Larry Hastings2f936352014-08-05 14:04:04 +10005696
5697/*[clinic input]
5698os.sched_yield
5699
5700Voluntarily relinquish the CPU.
5701[clinic start generated code]*/
5702
Larry Hastings2f936352014-08-05 14:04:04 +10005703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005704os_sched_yield_impl(PyObject *module)
5705/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005706{
5707 if (sched_yield())
5708 return posix_error();
5709 Py_RETURN_NONE;
5710}
5711
Benjamin Peterson2740af82011-08-02 17:41:34 -05005712#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005713/* The minimum number of CPUs allocated in a cpu_set_t */
5714static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005715
Larry Hastings2f936352014-08-05 14:04:04 +10005716/*[clinic input]
5717os.sched_setaffinity
5718 pid: pid_t
5719 mask : object
5720 /
5721
5722Set the CPU affinity of the process identified by pid to mask.
5723
5724mask should be an iterable of integers identifying CPUs.
5725[clinic start generated code]*/
5726
Larry Hastings2f936352014-08-05 14:04:04 +10005727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005728os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5729/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005730{
Antoine Pitrou84869872012-08-04 16:16:35 +02005731 int ncpus;
5732 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005733 cpu_set_t *cpu_set = NULL;
5734 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005735
Larry Hastings2f936352014-08-05 14:04:04 +10005736 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005737 if (iterator == NULL)
5738 return NULL;
5739
5740 ncpus = NCPUS_START;
5741 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005742 cpu_set = CPU_ALLOC(ncpus);
5743 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005744 PyErr_NoMemory();
5745 goto error;
5746 }
Larry Hastings2f936352014-08-05 14:04:04 +10005747 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005748
5749 while ((item = PyIter_Next(iterator))) {
5750 long cpu;
5751 if (!PyLong_Check(item)) {
5752 PyErr_Format(PyExc_TypeError,
5753 "expected an iterator of ints, "
5754 "but iterator yielded %R",
5755 Py_TYPE(item));
5756 Py_DECREF(item);
5757 goto error;
5758 }
5759 cpu = PyLong_AsLong(item);
5760 Py_DECREF(item);
5761 if (cpu < 0) {
5762 if (!PyErr_Occurred())
5763 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5764 goto error;
5765 }
5766 if (cpu > INT_MAX - 1) {
5767 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5768 goto error;
5769 }
5770 if (cpu >= ncpus) {
5771 /* Grow CPU mask to fit the CPU number */
5772 int newncpus = ncpus;
5773 cpu_set_t *newmask;
5774 size_t newsetsize;
5775 while (newncpus <= cpu) {
5776 if (newncpus > INT_MAX / 2)
5777 newncpus = cpu + 1;
5778 else
5779 newncpus = newncpus * 2;
5780 }
5781 newmask = CPU_ALLOC(newncpus);
5782 if (newmask == NULL) {
5783 PyErr_NoMemory();
5784 goto error;
5785 }
5786 newsetsize = CPU_ALLOC_SIZE(newncpus);
5787 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005788 memcpy(newmask, cpu_set, setsize);
5789 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005790 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005791 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005792 ncpus = newncpus;
5793 }
Larry Hastings2f936352014-08-05 14:04:04 +10005794 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005795 }
5796 Py_CLEAR(iterator);
5797
Larry Hastings2f936352014-08-05 14:04:04 +10005798 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 posix_error();
5800 goto error;
5801 }
Larry Hastings2f936352014-08-05 14:04:04 +10005802 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005803 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005804
5805error:
Larry Hastings2f936352014-08-05 14:04:04 +10005806 if (cpu_set)
5807 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005808 Py_XDECREF(iterator);
5809 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005810}
5811
Larry Hastings2f936352014-08-05 14:04:04 +10005812
5813/*[clinic input]
5814os.sched_getaffinity
5815 pid: pid_t
5816 /
5817
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005818Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005819
5820The affinity is returned as a set of CPU identifiers.
5821[clinic start generated code]*/
5822
Larry Hastings2f936352014-08-05 14:04:04 +10005823static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005824os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005825/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005826{
Antoine Pitrou84869872012-08-04 16:16:35 +02005827 int cpu, ncpus, count;
5828 size_t setsize;
5829 cpu_set_t *mask = NULL;
5830 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005831
Antoine Pitrou84869872012-08-04 16:16:35 +02005832 ncpus = NCPUS_START;
5833 while (1) {
5834 setsize = CPU_ALLOC_SIZE(ncpus);
5835 mask = CPU_ALLOC(ncpus);
5836 if (mask == NULL)
5837 return PyErr_NoMemory();
5838 if (sched_getaffinity(pid, setsize, mask) == 0)
5839 break;
5840 CPU_FREE(mask);
5841 if (errno != EINVAL)
5842 return posix_error();
5843 if (ncpus > INT_MAX / 2) {
5844 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5845 "a large enough CPU set");
5846 return NULL;
5847 }
5848 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005849 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005850
5851 res = PySet_New(NULL);
5852 if (res == NULL)
5853 goto error;
5854 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5855 if (CPU_ISSET_S(cpu, setsize, mask)) {
5856 PyObject *cpu_num = PyLong_FromLong(cpu);
5857 --count;
5858 if (cpu_num == NULL)
5859 goto error;
5860 if (PySet_Add(res, cpu_num)) {
5861 Py_DECREF(cpu_num);
5862 goto error;
5863 }
5864 Py_DECREF(cpu_num);
5865 }
5866 }
5867 CPU_FREE(mask);
5868 return res;
5869
5870error:
5871 if (mask)
5872 CPU_FREE(mask);
5873 Py_XDECREF(res);
5874 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005875}
5876
Benjamin Peterson2740af82011-08-02 17:41:34 -05005877#endif /* HAVE_SCHED_SETAFFINITY */
5878
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005879#endif /* HAVE_SCHED_H */
5880
Larry Hastings2f936352014-08-05 14:04:04 +10005881
Neal Norwitzb59798b2003-03-21 01:43:31 +00005882/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005883/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5884#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005885#define DEV_PTY_FILE "/dev/ptc"
5886#define HAVE_DEV_PTMX
5887#else
5888#define DEV_PTY_FILE "/dev/ptmx"
5889#endif
5890
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005891#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005892#ifdef HAVE_PTY_H
5893#include <pty.h>
5894#else
5895#ifdef HAVE_LIBUTIL_H
5896#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005897#else
5898#ifdef HAVE_UTIL_H
5899#include <util.h>
5900#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005901#endif /* HAVE_LIBUTIL_H */
5902#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005903#ifdef HAVE_STROPTS_H
5904#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005905#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005906#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005907
Larry Hastings2f936352014-08-05 14:04:04 +10005908
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005909#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005910/*[clinic input]
5911os.openpty
5912
5913Open a pseudo-terminal.
5914
5915Return a tuple of (master_fd, slave_fd) containing open file descriptors
5916for both the master and slave ends.
5917[clinic start generated code]*/
5918
Larry Hastings2f936352014-08-05 14:04:04 +10005919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005920os_openpty_impl(PyObject *module)
5921/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005922{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005923 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005924#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005926#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005927#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005929#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005931#endif
5932#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933
Thomas Wouters70c21a12000-07-14 14:28:33 +00005934#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005936 goto posix_error;
5937
5938 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5939 goto error;
5940 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5941 goto error;
5942
Neal Norwitzb59798b2003-03-21 01:43:31 +00005943#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5945 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005946 goto posix_error;
5947 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5948 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005949
Victor Stinnerdaf45552013-08-28 00:53:59 +02005950 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005952 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005954#else
Victor Stinner000de532013-11-25 23:19:58 +01005955 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005957 goto posix_error;
5958
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005960
Victor Stinner8c62be82010-05-06 00:08:46 +00005961 /* change permission of slave */
5962 if (grantpt(master_fd) < 0) {
5963 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005966
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 /* unlock slave */
5968 if (unlockpt(master_fd) < 0) {
5969 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005970 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005972
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005974
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 slave_name = ptsname(master_fd); /* get name of slave */
5976 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005977 goto posix_error;
5978
5979 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005980 if (slave_fd == -1)
5981 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005982
5983 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5984 goto posix_error;
5985
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005986#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5988 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005989#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005991#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005992#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005993#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005994
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005996
Victor Stinnerdaf45552013-08-28 00:53:59 +02005997posix_error:
5998 posix_error();
5999error:
6000 if (master_fd != -1)
6001 close(master_fd);
6002 if (slave_fd != -1)
6003 close(slave_fd);
6004 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006005}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006006#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006007
Larry Hastings2f936352014-08-05 14:04:04 +10006008
Fred Drake8cef4cf2000-06-28 16:40:38 +00006009#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006010/*[clinic input]
6011os.forkpty
6012
6013Fork a new process with a new pseudo-terminal as controlling tty.
6014
6015Returns a tuple of (pid, master_fd).
6016Like fork(), return pid of 0 to the child process,
6017and pid of child to the parent process.
6018To both, return fd of newly opened pseudo-terminal.
6019[clinic start generated code]*/
6020
Larry Hastings2f936352014-08-05 14:04:04 +10006021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006022os_forkpty_impl(PyObject *module)
6023/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006024{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006025 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006027
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006028 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 pid = forkpty(&master_fd, NULL, NULL, NULL);
6030 if (pid == 0) {
6031 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006032 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 } else {
6034 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006035 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 }
6037 if (pid == -1)
6038 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006040}
Larry Hastings2f936352014-08-05 14:04:04 +10006041#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006042
Ross Lagerwall7807c352011-03-17 20:20:30 +02006043
Guido van Rossumad0ee831995-03-01 10:34:45 +00006044#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006045/*[clinic input]
6046os.getegid
6047
6048Return the current process's effective group id.
6049[clinic start generated code]*/
6050
Larry Hastings2f936352014-08-05 14:04:04 +10006051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006052os_getegid_impl(PyObject *module)
6053/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006054{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006055 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006056}
Larry Hastings2f936352014-08-05 14:04:04 +10006057#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006059
Guido van Rossumad0ee831995-03-01 10:34:45 +00006060#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006061/*[clinic input]
6062os.geteuid
6063
6064Return the current process's effective user id.
6065[clinic start generated code]*/
6066
Larry Hastings2f936352014-08-05 14:04:04 +10006067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006068os_geteuid_impl(PyObject *module)
6069/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006070{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006071 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006072}
Larry Hastings2f936352014-08-05 14:04:04 +10006073#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006075
Guido van Rossumad0ee831995-03-01 10:34:45 +00006076#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006077/*[clinic input]
6078os.getgid
6079
6080Return the current process's group id.
6081[clinic start generated code]*/
6082
Larry Hastings2f936352014-08-05 14:04:04 +10006083static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006084os_getgid_impl(PyObject *module)
6085/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006086{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006087 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006088}
Larry Hastings2f936352014-08-05 14:04:04 +10006089#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006091
Berker Peksag39404992016-09-15 20:45:16 +03006092#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006093/*[clinic input]
6094os.getpid
6095
6096Return the current process id.
6097[clinic start generated code]*/
6098
Larry Hastings2f936352014-08-05 14:04:04 +10006099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006100os_getpid_impl(PyObject *module)
6101/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006102{
Victor Stinner8c62be82010-05-06 00:08:46 +00006103 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006104}
Berker Peksag39404992016-09-15 20:45:16 +03006105#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006106
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006107#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006108
6109/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006110PyDoc_STRVAR(posix_getgrouplist__doc__,
6111"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6112Returns a list of groups to which a user belongs.\n\n\
6113 user: username to lookup\n\
6114 group: base group id of the user");
6115
6116static PyObject *
6117posix_getgrouplist(PyObject *self, PyObject *args)
6118{
6119#ifdef NGROUPS_MAX
6120#define MAX_GROUPS NGROUPS_MAX
6121#else
6122 /* defined to be 16 on Solaris7, so this should be a small number */
6123#define MAX_GROUPS 64
6124#endif
6125
6126 const char *user;
6127 int i, ngroups;
6128 PyObject *list;
6129#ifdef __APPLE__
6130 int *groups, basegid;
6131#else
6132 gid_t *groups, basegid;
6133#endif
6134 ngroups = MAX_GROUPS;
6135
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006136#ifdef __APPLE__
6137 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006138 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006139#else
6140 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6141 _Py_Gid_Converter, &basegid))
6142 return NULL;
6143#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006144
6145#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006146 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006147#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006148 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006149#endif
6150 if (groups == NULL)
6151 return PyErr_NoMemory();
6152
6153 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6154 PyMem_Del(groups);
6155 return posix_error();
6156 }
6157
6158 list = PyList_New(ngroups);
6159 if (list == NULL) {
6160 PyMem_Del(groups);
6161 return NULL;
6162 }
6163
6164 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006165#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006166 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006167#else
6168 PyObject *o = _PyLong_FromGid(groups[i]);
6169#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006170 if (o == NULL) {
6171 Py_DECREF(list);
6172 PyMem_Del(groups);
6173 return NULL;
6174 }
6175 PyList_SET_ITEM(list, i, o);
6176 }
6177
6178 PyMem_Del(groups);
6179
6180 return list;
6181}
Larry Hastings2f936352014-08-05 14:04:04 +10006182#endif /* HAVE_GETGROUPLIST */
6183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006184
Fred Drakec9680921999-12-13 16:37:25 +00006185#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006186/*[clinic input]
6187os.getgroups
6188
6189Return list of supplemental group IDs for the process.
6190[clinic start generated code]*/
6191
Larry Hastings2f936352014-08-05 14:04:04 +10006192static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006193os_getgroups_impl(PyObject *module)
6194/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006195{
6196 PyObject *result = NULL;
6197
Fred Drakec9680921999-12-13 16:37:25 +00006198#ifdef NGROUPS_MAX
6199#define MAX_GROUPS NGROUPS_MAX
6200#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006202#define MAX_GROUPS 64
6203#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006205
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006206 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006207 * This is a helper variable to store the intermediate result when
6208 * that happens.
6209 *
6210 * To keep the code readable the OSX behaviour is unconditional,
6211 * according to the POSIX spec this should be safe on all unix-y
6212 * systems.
6213 */
6214 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006216
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006217#ifdef __APPLE__
6218 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6219 * there are more groups than can fit in grouplist. Therefore, on OS X
6220 * always first call getgroups with length 0 to get the actual number
6221 * of groups.
6222 */
6223 n = getgroups(0, NULL);
6224 if (n < 0) {
6225 return posix_error();
6226 } else if (n <= MAX_GROUPS) {
6227 /* groups will fit in existing array */
6228 alt_grouplist = grouplist;
6229 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006230 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006231 if (alt_grouplist == NULL) {
Zackery Spytz602d3072018-12-07 05:17:43 -07006232 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006233 }
6234 }
6235
6236 n = getgroups(n, alt_grouplist);
6237 if (n == -1) {
6238 if (alt_grouplist != grouplist) {
6239 PyMem_Free(alt_grouplist);
6240 }
6241 return posix_error();
6242 }
6243#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006244 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006245 if (n < 0) {
6246 if (errno == EINVAL) {
6247 n = getgroups(0, NULL);
6248 if (n == -1) {
6249 return posix_error();
6250 }
6251 if (n == 0) {
6252 /* Avoid malloc(0) */
6253 alt_grouplist = grouplist;
6254 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006255 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006256 if (alt_grouplist == NULL) {
Zackery Spytz602d3072018-12-07 05:17:43 -07006257 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006258 }
6259 n = getgroups(n, alt_grouplist);
6260 if (n == -1) {
6261 PyMem_Free(alt_grouplist);
6262 return posix_error();
6263 }
6264 }
6265 } else {
6266 return posix_error();
6267 }
6268 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006269#endif
6270
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006271 result = PyList_New(n);
6272 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 int i;
6274 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006275 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006277 Py_DECREF(result);
6278 result = NULL;
6279 break;
Fred Drakec9680921999-12-13 16:37:25 +00006280 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006282 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006283 }
6284
6285 if (alt_grouplist != grouplist) {
6286 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006287 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006288
Fred Drakec9680921999-12-13 16:37:25 +00006289 return result;
6290}
Larry Hastings2f936352014-08-05 14:04:04 +10006291#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006292
Antoine Pitroub7572f02009-12-02 20:46:48 +00006293#ifdef HAVE_INITGROUPS
6294PyDoc_STRVAR(posix_initgroups__doc__,
6295"initgroups(username, gid) -> None\n\n\
6296Call the system initgroups() to initialize the group access list with all of\n\
6297the groups of which the specified username is a member, plus the specified\n\
6298group id.");
6299
Larry Hastings2f936352014-08-05 14:04:04 +10006300/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006301static PyObject *
6302posix_initgroups(PyObject *self, PyObject *args)
6303{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006304 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006305 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006306 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006307#ifdef __APPLE__
6308 int gid;
6309#else
6310 gid_t gid;
6311#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006312
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006313#ifdef __APPLE__
6314 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6315 PyUnicode_FSConverter, &oname,
6316 &gid))
6317#else
6318 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6319 PyUnicode_FSConverter, &oname,
6320 _Py_Gid_Converter, &gid))
6321#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006323 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006324
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006325 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006326 Py_DECREF(oname);
6327 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006329
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006330 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006331}
Larry Hastings2f936352014-08-05 14:04:04 +10006332#endif /* HAVE_INITGROUPS */
6333
Antoine Pitroub7572f02009-12-02 20:46:48 +00006334
Martin v. Löwis606edc12002-06-13 21:09:11 +00006335#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006336/*[clinic input]
6337os.getpgid
6338
6339 pid: pid_t
6340
6341Call the system call getpgid(), and return the result.
6342[clinic start generated code]*/
6343
Larry Hastings2f936352014-08-05 14:04:04 +10006344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006345os_getpgid_impl(PyObject *module, pid_t pid)
6346/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006347{
6348 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 if (pgid < 0)
6350 return posix_error();
6351 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006352}
6353#endif /* HAVE_GETPGID */
6354
6355
Guido van Rossumb6775db1994-08-01 11:34:53 +00006356#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006357/*[clinic input]
6358os.getpgrp
6359
6360Return the current process group id.
6361[clinic start generated code]*/
6362
Larry Hastings2f936352014-08-05 14:04:04 +10006363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006364os_getpgrp_impl(PyObject *module)
6365/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006366{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006367#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006369#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006371#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006372}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006374
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006375
Guido van Rossumb6775db1994-08-01 11:34:53 +00006376#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006377/*[clinic input]
6378os.setpgrp
6379
6380Make the current process the leader of its process group.
6381[clinic start generated code]*/
6382
Larry Hastings2f936352014-08-05 14:04:04 +10006383static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006384os_setpgrp_impl(PyObject *module)
6385/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006386{
Guido van Rossum64933891994-10-20 21:56:42 +00006387#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006389#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006391#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006393 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006394}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006395#endif /* HAVE_SETPGRP */
6396
Guido van Rossumad0ee831995-03-01 10:34:45 +00006397#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006398
6399#ifdef MS_WINDOWS
6400#include <tlhelp32.h>
6401
6402static PyObject*
6403win32_getppid()
6404{
6405 HANDLE snapshot;
6406 pid_t mypid;
6407 PyObject* result = NULL;
6408 BOOL have_record;
6409 PROCESSENTRY32 pe;
6410
6411 mypid = getpid(); /* This function never fails */
6412
6413 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6414 if (snapshot == INVALID_HANDLE_VALUE)
6415 return PyErr_SetFromWindowsErr(GetLastError());
6416
6417 pe.dwSize = sizeof(pe);
6418 have_record = Process32First(snapshot, &pe);
6419 while (have_record) {
6420 if (mypid == (pid_t)pe.th32ProcessID) {
6421 /* We could cache the ulong value in a static variable. */
6422 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6423 break;
6424 }
6425
6426 have_record = Process32Next(snapshot, &pe);
6427 }
6428
6429 /* If our loop exits and our pid was not found (result will be NULL)
6430 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6431 * error anyway, so let's raise it. */
6432 if (!result)
6433 result = PyErr_SetFromWindowsErr(GetLastError());
6434
6435 CloseHandle(snapshot);
6436
6437 return result;
6438}
6439#endif /*MS_WINDOWS*/
6440
Larry Hastings2f936352014-08-05 14:04:04 +10006441
6442/*[clinic input]
6443os.getppid
6444
6445Return the parent's process id.
6446
6447If the parent process has already exited, Windows machines will still
6448return its id; others systems will return the id of the 'init' process (1).
6449[clinic start generated code]*/
6450
Larry Hastings2f936352014-08-05 14:04:04 +10006451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006452os_getppid_impl(PyObject *module)
6453/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006454{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006455#ifdef MS_WINDOWS
6456 return win32_getppid();
6457#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006459#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006460}
6461#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006462
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006463
Fred Drake12c6e2d1999-12-14 21:25:03 +00006464#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006465/*[clinic input]
6466os.getlogin
6467
6468Return the actual login name.
6469[clinic start generated code]*/
6470
Larry Hastings2f936352014-08-05 14:04:04 +10006471static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006472os_getlogin_impl(PyObject *module)
6473/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006474{
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006476#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006477 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006478 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006479
6480 if (GetUserNameW(user_name, &num_chars)) {
6481 /* num_chars is the number of unicode chars plus null terminator */
6482 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006483 }
6484 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006485 result = PyErr_SetFromWindowsErr(GetLastError());
6486#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 char *name;
6488 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006489
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 errno = 0;
6491 name = getlogin();
6492 if (name == NULL) {
6493 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006494 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006495 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006496 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 }
6498 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006499 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006501#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006502 return result;
6503}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006504#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006505
Larry Hastings2f936352014-08-05 14:04:04 +10006506
Guido van Rossumad0ee831995-03-01 10:34:45 +00006507#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006508/*[clinic input]
6509os.getuid
6510
6511Return the current process's user id.
6512[clinic start generated code]*/
6513
Larry Hastings2f936352014-08-05 14:04:04 +10006514static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006515os_getuid_impl(PyObject *module)
6516/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006517{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006518 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006519}
Larry Hastings2f936352014-08-05 14:04:04 +10006520#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006521
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006522
Brian Curtineb24d742010-04-12 17:16:38 +00006523#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006524#define HAVE_KILL
6525#endif /* MS_WINDOWS */
6526
6527#ifdef HAVE_KILL
6528/*[clinic input]
6529os.kill
6530
6531 pid: pid_t
6532 signal: Py_ssize_t
6533 /
6534
6535Kill a process with a signal.
6536[clinic start generated code]*/
6537
Larry Hastings2f936352014-08-05 14:04:04 +10006538static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006539os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6540/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006541#ifndef MS_WINDOWS
6542{
6543 if (kill(pid, (int)signal) == -1)
6544 return posix_error();
6545 Py_RETURN_NONE;
6546}
6547#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006548{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006549 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006550 DWORD sig = (DWORD)signal;
6551 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006553
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 /* Console processes which share a common console can be sent CTRL+C or
6555 CTRL+BREAK events, provided they handle said events. */
6556 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006557 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 err = GetLastError();
6559 PyErr_SetFromWindowsErr(err);
6560 }
6561 else
6562 Py_RETURN_NONE;
6563 }
Brian Curtineb24d742010-04-12 17:16:38 +00006564
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6566 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006567 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 if (handle == NULL) {
6569 err = GetLastError();
6570 return PyErr_SetFromWindowsErr(err);
6571 }
Brian Curtineb24d742010-04-12 17:16:38 +00006572
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 if (TerminateProcess(handle, sig) == 0) {
6574 err = GetLastError();
6575 result = PyErr_SetFromWindowsErr(err);
6576 } else {
6577 Py_INCREF(Py_None);
6578 result = Py_None;
6579 }
Brian Curtineb24d742010-04-12 17:16:38 +00006580
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 CloseHandle(handle);
6582 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006583}
Larry Hastings2f936352014-08-05 14:04:04 +10006584#endif /* !MS_WINDOWS */
6585#endif /* HAVE_KILL */
6586
6587
6588#ifdef HAVE_KILLPG
6589/*[clinic input]
6590os.killpg
6591
6592 pgid: pid_t
6593 signal: int
6594 /
6595
6596Kill a process group with a signal.
6597[clinic start generated code]*/
6598
Larry Hastings2f936352014-08-05 14:04:04 +10006599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006600os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6601/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006602{
6603 /* XXX some man pages make the `pgid` parameter an int, others
6604 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6605 take the same type. Moreover, pid_t is always at least as wide as
6606 int (else compilation of this module fails), which is safe. */
6607 if (killpg(pgid, signal) == -1)
6608 return posix_error();
6609 Py_RETURN_NONE;
6610}
6611#endif /* HAVE_KILLPG */
6612
Brian Curtineb24d742010-04-12 17:16:38 +00006613
Guido van Rossumc0125471996-06-28 18:55:32 +00006614#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006615#ifdef HAVE_SYS_LOCK_H
6616#include <sys/lock.h>
6617#endif
6618
Larry Hastings2f936352014-08-05 14:04:04 +10006619/*[clinic input]
6620os.plock
6621 op: int
6622 /
6623
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006624Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006625[clinic start generated code]*/
6626
Larry Hastings2f936352014-08-05 14:04:04 +10006627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006628os_plock_impl(PyObject *module, int op)
6629/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006630{
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 if (plock(op) == -1)
6632 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006633 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006634}
Larry Hastings2f936352014-08-05 14:04:04 +10006635#endif /* HAVE_PLOCK */
6636
Guido van Rossumc0125471996-06-28 18:55:32 +00006637
Guido van Rossumb6775db1994-08-01 11:34:53 +00006638#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006639/*[clinic input]
6640os.setuid
6641
6642 uid: uid_t
6643 /
6644
6645Set the current process's user id.
6646[clinic start generated code]*/
6647
Larry Hastings2f936352014-08-05 14:04:04 +10006648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006649os_setuid_impl(PyObject *module, uid_t uid)
6650/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006651{
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 if (setuid(uid) < 0)
6653 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006654 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006655}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006656#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006657
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006658
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006659#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006660/*[clinic input]
6661os.seteuid
6662
6663 euid: uid_t
6664 /
6665
6666Set the current process's effective user id.
6667[clinic start generated code]*/
6668
Larry Hastings2f936352014-08-05 14:04:04 +10006669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006670os_seteuid_impl(PyObject *module, uid_t euid)
6671/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006672{
6673 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006675 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006676}
6677#endif /* HAVE_SETEUID */
6678
Larry Hastings2f936352014-08-05 14:04:04 +10006679
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006680#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006681/*[clinic input]
6682os.setegid
6683
6684 egid: gid_t
6685 /
6686
6687Set the current process's effective group id.
6688[clinic start generated code]*/
6689
Larry Hastings2f936352014-08-05 14:04:04 +10006690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006691os_setegid_impl(PyObject *module, gid_t egid)
6692/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006693{
6694 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006696 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006697}
6698#endif /* HAVE_SETEGID */
6699
Larry Hastings2f936352014-08-05 14:04:04 +10006700
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006701#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006702/*[clinic input]
6703os.setreuid
6704
6705 ruid: uid_t
6706 euid: uid_t
6707 /
6708
6709Set the current process's real and effective user ids.
6710[clinic start generated code]*/
6711
Larry Hastings2f936352014-08-05 14:04:04 +10006712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006713os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6714/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006715{
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 if (setreuid(ruid, euid) < 0) {
6717 return posix_error();
6718 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006719 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006721}
6722#endif /* HAVE_SETREUID */
6723
Larry Hastings2f936352014-08-05 14:04:04 +10006724
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006725#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006726/*[clinic input]
6727os.setregid
6728
6729 rgid: gid_t
6730 egid: gid_t
6731 /
6732
6733Set the current process's real and effective group ids.
6734[clinic start generated code]*/
6735
Larry Hastings2f936352014-08-05 14:04:04 +10006736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006737os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6738/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006739{
6740 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006741 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006742 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006743}
6744#endif /* HAVE_SETREGID */
6745
Larry Hastings2f936352014-08-05 14:04:04 +10006746
Guido van Rossumb6775db1994-08-01 11:34:53 +00006747#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006748/*[clinic input]
6749os.setgid
6750 gid: gid_t
6751 /
6752
6753Set the current process's group id.
6754[clinic start generated code]*/
6755
Larry Hastings2f936352014-08-05 14:04:04 +10006756static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006757os_setgid_impl(PyObject *module, gid_t gid)
6758/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006759{
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 if (setgid(gid) < 0)
6761 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006762 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006763}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006764#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006765
Larry Hastings2f936352014-08-05 14:04:04 +10006766
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006767#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006768/*[clinic input]
6769os.setgroups
6770
6771 groups: object
6772 /
6773
6774Set the groups of the current process to list.
6775[clinic start generated code]*/
6776
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006778os_setgroups(PyObject *module, PyObject *groups)
6779/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006780{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006781 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006783
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (!PySequence_Check(groups)) {
6785 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6786 return NULL;
6787 }
6788 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006789 if (len < 0) {
6790 return NULL;
6791 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 if (len > MAX_GROUPS) {
6793 PyErr_SetString(PyExc_ValueError, "too many groups");
6794 return NULL;
6795 }
6796 for(i = 0; i < len; i++) {
6797 PyObject *elem;
6798 elem = PySequence_GetItem(groups, i);
6799 if (!elem)
6800 return NULL;
6801 if (!PyLong_Check(elem)) {
6802 PyErr_SetString(PyExc_TypeError,
6803 "groups must be integers");
6804 Py_DECREF(elem);
6805 return NULL;
6806 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006807 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 Py_DECREF(elem);
6809 return NULL;
6810 }
6811 }
6812 Py_DECREF(elem);
6813 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006814
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 if (setgroups(len, grouplist) < 0)
6816 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006817 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006818}
6819#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006820
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006821#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6822static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006823wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006824{
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 PyObject *result;
6826 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006827 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006828
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 if (pid == -1)
6830 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006831
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 if (struct_rusage == NULL) {
6833 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6834 if (m == NULL)
6835 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006836 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 Py_DECREF(m);
6838 if (struct_rusage == NULL)
6839 return NULL;
6840 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006841
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6843 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6844 if (!result)
6845 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846
6847#ifndef doubletime
6848#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6849#endif
6850
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006852 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006854 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6857 SET_INT(result, 2, ru->ru_maxrss);
6858 SET_INT(result, 3, ru->ru_ixrss);
6859 SET_INT(result, 4, ru->ru_idrss);
6860 SET_INT(result, 5, ru->ru_isrss);
6861 SET_INT(result, 6, ru->ru_minflt);
6862 SET_INT(result, 7, ru->ru_majflt);
6863 SET_INT(result, 8, ru->ru_nswap);
6864 SET_INT(result, 9, ru->ru_inblock);
6865 SET_INT(result, 10, ru->ru_oublock);
6866 SET_INT(result, 11, ru->ru_msgsnd);
6867 SET_INT(result, 12, ru->ru_msgrcv);
6868 SET_INT(result, 13, ru->ru_nsignals);
6869 SET_INT(result, 14, ru->ru_nvcsw);
6870 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006871#undef SET_INT
6872
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 if (PyErr_Occurred()) {
6874 Py_DECREF(result);
6875 return NULL;
6876 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006879}
6880#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6881
Larry Hastings2f936352014-08-05 14:04:04 +10006882
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006883#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006884/*[clinic input]
6885os.wait3
6886
6887 options: int
6888Wait for completion of a child process.
6889
6890Returns a tuple of information about the child process:
6891 (pid, status, rusage)
6892[clinic start generated code]*/
6893
Larry Hastings2f936352014-08-05 14:04:04 +10006894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006895os_wait3_impl(PyObject *module, int options)
6896/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006897{
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006900 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 WAIT_TYPE status;
6902 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006903
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006904 do {
6905 Py_BEGIN_ALLOW_THREADS
6906 pid = wait3(&status, options, &ru);
6907 Py_END_ALLOW_THREADS
6908 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6909 if (pid < 0)
6910 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911
Victor Stinner4195b5c2012-02-08 23:03:19 +01006912 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913}
6914#endif /* HAVE_WAIT3 */
6915
Larry Hastings2f936352014-08-05 14:04:04 +10006916
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006918/*[clinic input]
6919
6920os.wait4
6921
6922 pid: pid_t
6923 options: int
6924
6925Wait for completion of a specific child process.
6926
6927Returns a tuple of information about the child process:
6928 (pid, status, rusage)
6929[clinic start generated code]*/
6930
Larry Hastings2f936352014-08-05 14:04:04 +10006931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006932os_wait4_impl(PyObject *module, pid_t pid, int options)
6933/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006934{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006937 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 WAIT_TYPE status;
6939 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006941 do {
6942 Py_BEGIN_ALLOW_THREADS
6943 res = wait4(pid, &status, options, &ru);
6944 Py_END_ALLOW_THREADS
6945 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6946 if (res < 0)
6947 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006949 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950}
6951#endif /* HAVE_WAIT4 */
6952
Larry Hastings2f936352014-08-05 14:04:04 +10006953
Ross Lagerwall7807c352011-03-17 20:20:30 +02006954#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006955/*[clinic input]
6956os.waitid
6957
6958 idtype: idtype_t
6959 Must be one of be P_PID, P_PGID or P_ALL.
6960 id: id_t
6961 The id to wait on.
6962 options: int
6963 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6964 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6965 /
6966
6967Returns the result of waiting for a process or processes.
6968
6969Returns either waitid_result or None if WNOHANG is specified and there are
6970no children in a waitable state.
6971[clinic start generated code]*/
6972
Larry Hastings2f936352014-08-05 14:04:04 +10006973static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006974os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6975/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006976{
6977 PyObject *result;
6978 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006979 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006980 siginfo_t si;
6981 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006982
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006983 do {
6984 Py_BEGIN_ALLOW_THREADS
6985 res = waitid(idtype, id, &si, options);
6986 Py_END_ALLOW_THREADS
6987 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6988 if (res < 0)
6989 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006990
6991 if (si.si_pid == 0)
6992 Py_RETURN_NONE;
6993
6994 result = PyStructSequence_New(&WaitidResultType);
6995 if (!result)
6996 return NULL;
6997
6998 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006999 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007000 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7001 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7002 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7003 if (PyErr_Occurred()) {
7004 Py_DECREF(result);
7005 return NULL;
7006 }
7007
7008 return result;
7009}
Larry Hastings2f936352014-08-05 14:04:04 +10007010#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007011
Larry Hastings2f936352014-08-05 14:04:04 +10007012
7013#if defined(HAVE_WAITPID)
7014/*[clinic input]
7015os.waitpid
7016 pid: pid_t
7017 options: int
7018 /
7019
7020Wait for completion of a given child process.
7021
7022Returns a tuple of information regarding the child process:
7023 (pid, status)
7024
7025The options argument is ignored on Windows.
7026[clinic start generated code]*/
7027
Larry Hastings2f936352014-08-05 14:04:04 +10007028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007029os_waitpid_impl(PyObject *module, pid_t pid, int options)
7030/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007031{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007032 pid_t res;
7033 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 WAIT_TYPE status;
7035 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007036
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007037 do {
7038 Py_BEGIN_ALLOW_THREADS
7039 res = waitpid(pid, &status, options);
7040 Py_END_ALLOW_THREADS
7041 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7042 if (res < 0)
7043 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007044
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007045 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007046}
Tim Petersab034fa2002-02-01 11:27:43 +00007047#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007048/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007049/*[clinic input]
7050os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007051 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007052 options: int
7053 /
7054
7055Wait for completion of a given process.
7056
7057Returns a tuple of information regarding the process:
7058 (pid, status << 8)
7059
7060The options argument is ignored on Windows.
7061[clinic start generated code]*/
7062
Larry Hastings2f936352014-08-05 14:04:04 +10007063static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007064os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007065/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007066{
7067 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007068 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007069 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007070
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007071 do {
7072 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007073 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007074 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007075 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007076 Py_END_ALLOW_THREADS
7077 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007078 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007079 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007080
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007082 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007083}
Larry Hastings2f936352014-08-05 14:04:04 +10007084#endif
7085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007086
Guido van Rossumad0ee831995-03-01 10:34:45 +00007087#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007088/*[clinic input]
7089os.wait
7090
7091Wait for completion of a child process.
7092
7093Returns a tuple of information about the child process:
7094 (pid, status)
7095[clinic start generated code]*/
7096
Larry Hastings2f936352014-08-05 14:04:04 +10007097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007098os_wait_impl(PyObject *module)
7099/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007100{
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007102 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 WAIT_TYPE status;
7104 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007105
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007106 do {
7107 Py_BEGIN_ALLOW_THREADS
7108 pid = wait(&status);
7109 Py_END_ALLOW_THREADS
7110 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7111 if (pid < 0)
7112 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007113
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007115}
Larry Hastings2f936352014-08-05 14:04:04 +10007116#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007118
Larry Hastings9cf065c2012-06-22 16:30:09 -07007119#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7120PyDoc_STRVAR(readlink__doc__,
7121"readlink(path, *, dir_fd=None) -> path\n\n\
7122Return a string representing the path to which the symbolic link points.\n\
7123\n\
7124If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7125 and path should be relative; path will then be relative to that directory.\n\
7126dir_fd may not be implemented on your platform.\n\
7127 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007128#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007129
Guido van Rossumb6775db1994-08-01 11:34:53 +00007130#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007131
Larry Hastings2f936352014-08-05 14:04:04 +10007132/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007133static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007135{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136 path_t path;
7137 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007138 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007139 ssize_t length;
7140 PyObject *return_value = NULL;
7141 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007142
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007144 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007145 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7146 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007147 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007148 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007149
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007151#ifdef HAVE_READLINKAT
7152 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007153 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007154 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007156 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007157 Py_END_ALLOW_THREADS
7158
7159 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007160 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007161 goto exit;
7162 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007163 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164
7165 if (PyUnicode_Check(path.object))
7166 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7167 else
7168 return_value = PyBytes_FromStringAndSize(buffer, length);
7169exit:
7170 path_cleanup(&path);
7171 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007172}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007173
Guido van Rossumb6775db1994-08-01 11:34:53 +00007174#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007175
Larry Hastings2f936352014-08-05 14:04:04 +10007176#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7177
7178static PyObject *
7179win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7180{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007181 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007182 DWORD n_bytes_returned;
7183 DWORD io_result;
7184 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007185 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007186 HANDLE reparse_point_handle;
7187
Martin Panter70214ad2016-08-04 02:38:59 +00007188 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7189 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007190 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007191
7192 static char *keywords[] = {"path", "dir_fd", NULL};
7193
7194 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7195 &po,
7196 dir_fd_unavailable, &dir_fd
7197 ))
7198 return NULL;
7199
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007200 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007201 if (path == NULL)
7202 return NULL;
7203
7204 /* First get a handle to the reparse point */
7205 Py_BEGIN_ALLOW_THREADS
7206 reparse_point_handle = CreateFileW(
7207 path,
7208 0,
7209 0,
7210 0,
7211 OPEN_EXISTING,
7212 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7213 0);
7214 Py_END_ALLOW_THREADS
7215
7216 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7217 return win32_error_object("readlink", po);
7218
7219 Py_BEGIN_ALLOW_THREADS
7220 /* New call DeviceIoControl to read the reparse point */
7221 io_result = DeviceIoControl(
7222 reparse_point_handle,
7223 FSCTL_GET_REPARSE_POINT,
7224 0, 0, /* in buffer */
7225 target_buffer, sizeof(target_buffer),
7226 &n_bytes_returned,
7227 0 /* we're not using OVERLAPPED_IO */
7228 );
7229 CloseHandle(reparse_point_handle);
7230 Py_END_ALLOW_THREADS
7231
7232 if (io_result==0)
7233 return win32_error_object("readlink", po);
7234
7235 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7236 {
7237 PyErr_SetString(PyExc_ValueError,
7238 "not a symbolic link");
7239 return NULL;
7240 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007241 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7242 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007243
7244 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007245 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007246 return result;
7247}
7248
7249#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7250
7251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007252
Larry Hastings9cf065c2012-06-22 16:30:09 -07007253#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007254
7255#if defined(MS_WINDOWS)
7256
7257/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007258static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007259
Larry Hastings9cf065c2012-06-22 16:30:09 -07007260static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007261check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262{
7263 HINSTANCE hKernel32;
7264 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007265 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007266 return 1;
7267 hKernel32 = GetModuleHandleW(L"KERNEL32");
7268 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7269 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007270 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007271}
7272
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007273/* Remove the last portion of the path - return 0 on success */
7274static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007275_dirnameW(WCHAR *path)
7276{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007278 size_t length = wcsnlen_s(path, MAX_PATH);
7279 if (length == MAX_PATH) {
7280 return -1;
7281 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007282
7283 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007284 for(ptr = path + length; ptr != path; ptr--) {
7285 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007286 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007287 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007288 }
7289 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007290 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291}
7292
Victor Stinner31b3b922013-06-05 01:49:17 +02007293/* Is this path absolute? */
7294static int
7295_is_absW(const WCHAR *path)
7296{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007297 return path[0] == L'\\' || path[0] == L'/' ||
7298 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007299}
7300
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007301/* join root and rest with a backslash - return 0 on success */
7302static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007303_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7304{
Victor Stinner31b3b922013-06-05 01:49:17 +02007305 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007306 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007307 }
7308
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007309 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7310 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007311 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007312
7313 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7314 return -1;
7315 }
7316
7317 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007318}
7319
Victor Stinner31b3b922013-06-05 01:49:17 +02007320/* Return True if the path at src relative to dest is a directory */
7321static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007322_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007323{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007324 WIN32_FILE_ATTRIBUTE_DATA src_info;
7325 WCHAR dest_parent[MAX_PATH];
7326 WCHAR src_resolved[MAX_PATH] = L"";
7327
7328 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007329 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7330 _dirnameW(dest_parent)) {
7331 return 0;
7332 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007334 if (_joinW(src_resolved, dest_parent, src)) {
7335 return 0;
7336 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007337 return (
7338 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7339 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7340 );
7341}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007342#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007343
Larry Hastings2f936352014-08-05 14:04:04 +10007344
7345/*[clinic input]
7346os.symlink
7347 src: path_t
7348 dst: path_t
7349 target_is_directory: bool = False
7350 *
7351 dir_fd: dir_fd(requires='symlinkat')=None
7352
7353# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7354
7355Create a symbolic link pointing to src named dst.
7356
7357target_is_directory is required on Windows if the target is to be
7358 interpreted as a directory. (On Windows, symlink requires
7359 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7360 target_is_directory is ignored on non-Windows platforms.
7361
7362If dir_fd is not None, it should be a file descriptor open to a directory,
7363 and path should be relative; path will then be relative to that directory.
7364dir_fd may not be implemented on your platform.
7365 If it is unavailable, using it will raise a NotImplementedError.
7366
7367[clinic start generated code]*/
7368
Larry Hastings2f936352014-08-05 14:04:04 +10007369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007370os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007371 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007372/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007373{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007374#ifdef MS_WINDOWS
7375 DWORD result;
7376#else
7377 int result;
7378#endif
7379
Larry Hastings9cf065c2012-06-22 16:30:09 -07007380#ifdef MS_WINDOWS
7381 if (!check_CreateSymbolicLink()) {
7382 PyErr_SetString(PyExc_NotImplementedError,
7383 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007384 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007385 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386 if (!win32_can_symlink) {
7387 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007388 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007389 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390#endif
7391
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007393
Larry Hastings9cf065c2012-06-22 16:30:09 -07007394 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007395 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007396 /* if src is a directory, ensure target_is_directory==1 */
7397 target_is_directory |= _check_dirW(src->wide, dst->wide);
7398 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7399 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007400 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007401 Py_END_ALLOW_THREADS
7402
Larry Hastings2f936352014-08-05 14:04:04 +10007403 if (!result)
7404 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405
7406#else
7407
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007408 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7409 PyErr_SetString(PyExc_ValueError,
7410 "symlink: src and dst must be the same type");
7411 return NULL;
7412 }
7413
Larry Hastings9cf065c2012-06-22 16:30:09 -07007414 Py_BEGIN_ALLOW_THREADS
7415#if HAVE_SYMLINKAT
7416 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007417 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007418 else
7419#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007420 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007421 Py_END_ALLOW_THREADS
7422
Larry Hastings2f936352014-08-05 14:04:04 +10007423 if (result)
7424 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007425#endif
7426
Larry Hastings2f936352014-08-05 14:04:04 +10007427 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007428}
7429#endif /* HAVE_SYMLINK */
7430
Larry Hastings9cf065c2012-06-22 16:30:09 -07007431
Brian Curtind40e6f72010-07-08 21:39:08 +00007432
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007433
Larry Hastings605a62d2012-06-24 04:33:36 -07007434static PyStructSequence_Field times_result_fields[] = {
7435 {"user", "user time"},
7436 {"system", "system time"},
7437 {"children_user", "user time of children"},
7438 {"children_system", "system time of children"},
7439 {"elapsed", "elapsed time since an arbitrary point in the past"},
7440 {NULL}
7441};
7442
7443PyDoc_STRVAR(times_result__doc__,
7444"times_result: Result from os.times().\n\n\
7445This object may be accessed either as a tuple of\n\
7446 (user, system, children_user, children_system, elapsed),\n\
7447or via the attributes user, system, children_user, children_system,\n\
7448and elapsed.\n\
7449\n\
7450See os.times for more information.");
7451
7452static PyStructSequence_Desc times_result_desc = {
7453 "times_result", /* name */
7454 times_result__doc__, /* doc */
7455 times_result_fields,
7456 5
7457};
7458
7459static PyTypeObject TimesResultType;
7460
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007461#ifdef MS_WINDOWS
7462#define HAVE_TIMES /* mandatory, for the method table */
7463#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007464
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007465#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007466
7467static PyObject *
7468build_times_result(double user, double system,
7469 double children_user, double children_system,
7470 double elapsed)
7471{
7472 PyObject *value = PyStructSequence_New(&TimesResultType);
7473 if (value == NULL)
7474 return NULL;
7475
7476#define SET(i, field) \
7477 { \
7478 PyObject *o = PyFloat_FromDouble(field); \
7479 if (!o) { \
7480 Py_DECREF(value); \
7481 return NULL; \
7482 } \
7483 PyStructSequence_SET_ITEM(value, i, o); \
7484 } \
7485
7486 SET(0, user);
7487 SET(1, system);
7488 SET(2, children_user);
7489 SET(3, children_system);
7490 SET(4, elapsed);
7491
7492#undef SET
7493
7494 return value;
7495}
7496
Larry Hastings605a62d2012-06-24 04:33:36 -07007497
Larry Hastings2f936352014-08-05 14:04:04 +10007498#ifndef MS_WINDOWS
7499#define NEED_TICKS_PER_SECOND
7500static long ticks_per_second = -1;
7501#endif /* MS_WINDOWS */
7502
7503/*[clinic input]
7504os.times
7505
7506Return a collection containing process timing information.
7507
7508The object returned behaves like a named tuple with these fields:
7509 (utime, stime, cutime, cstime, elapsed_time)
7510All fields are floating point numbers.
7511[clinic start generated code]*/
7512
Larry Hastings2f936352014-08-05 14:04:04 +10007513static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007514os_times_impl(PyObject *module)
7515/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007516#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007517{
Victor Stinner8c62be82010-05-06 00:08:46 +00007518 FILETIME create, exit, kernel, user;
7519 HANDLE hProc;
7520 hProc = GetCurrentProcess();
7521 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7522 /* The fields of a FILETIME structure are the hi and lo part
7523 of a 64-bit value expressed in 100 nanosecond units.
7524 1e7 is one second in such units; 1e-7 the inverse.
7525 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7526 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007527 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007528 (double)(user.dwHighDateTime*429.4967296 +
7529 user.dwLowDateTime*1e-7),
7530 (double)(kernel.dwHighDateTime*429.4967296 +
7531 kernel.dwLowDateTime*1e-7),
7532 (double)0,
7533 (double)0,
7534 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007535}
Larry Hastings2f936352014-08-05 14:04:04 +10007536#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007537{
Larry Hastings2f936352014-08-05 14:04:04 +10007538
7539
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007540 struct tms t;
7541 clock_t c;
7542 errno = 0;
7543 c = times(&t);
7544 if (c == (clock_t) -1)
7545 return posix_error();
7546 return build_times_result(
7547 (double)t.tms_utime / ticks_per_second,
7548 (double)t.tms_stime / ticks_per_second,
7549 (double)t.tms_cutime / ticks_per_second,
7550 (double)t.tms_cstime / ticks_per_second,
7551 (double)c / ticks_per_second);
7552}
Larry Hastings2f936352014-08-05 14:04:04 +10007553#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007554#endif /* HAVE_TIMES */
7555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007556
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007557#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007558/*[clinic input]
7559os.getsid
7560
7561 pid: pid_t
7562 /
7563
7564Call the system call getsid(pid) and return the result.
7565[clinic start generated code]*/
7566
Larry Hastings2f936352014-08-05 14:04:04 +10007567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007568os_getsid_impl(PyObject *module, pid_t pid)
7569/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007570{
Victor Stinner8c62be82010-05-06 00:08:46 +00007571 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 sid = getsid(pid);
7573 if (sid < 0)
7574 return posix_error();
7575 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007576}
7577#endif /* HAVE_GETSID */
7578
7579
Guido van Rossumb6775db1994-08-01 11:34:53 +00007580#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007581/*[clinic input]
7582os.setsid
7583
7584Call the system call setsid().
7585[clinic start generated code]*/
7586
Larry Hastings2f936352014-08-05 14:04:04 +10007587static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007588os_setsid_impl(PyObject *module)
7589/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007590{
Victor Stinner8c62be82010-05-06 00:08:46 +00007591 if (setsid() < 0)
7592 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007593 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007594}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007595#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007596
Larry Hastings2f936352014-08-05 14:04:04 +10007597
Guido van Rossumb6775db1994-08-01 11:34:53 +00007598#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007599/*[clinic input]
7600os.setpgid
7601
7602 pid: pid_t
7603 pgrp: pid_t
7604 /
7605
7606Call the system call setpgid(pid, pgrp).
7607[clinic start generated code]*/
7608
Larry Hastings2f936352014-08-05 14:04:04 +10007609static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007610os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7611/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007612{
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 if (setpgid(pid, pgrp) < 0)
7614 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007615 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007616}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007617#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007618
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007619
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007621/*[clinic input]
7622os.tcgetpgrp
7623
7624 fd: int
7625 /
7626
7627Return the process group associated with the terminal specified by fd.
7628[clinic start generated code]*/
7629
Larry Hastings2f936352014-08-05 14:04:04 +10007630static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007631os_tcgetpgrp_impl(PyObject *module, int fd)
7632/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007633{
7634 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007635 if (pgid < 0)
7636 return posix_error();
7637 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007638}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007639#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007641
Guido van Rossumb6775db1994-08-01 11:34:53 +00007642#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007643/*[clinic input]
7644os.tcsetpgrp
7645
7646 fd: int
7647 pgid: pid_t
7648 /
7649
7650Set the process group associated with the terminal specified by fd.
7651[clinic start generated code]*/
7652
Larry Hastings2f936352014-08-05 14:04:04 +10007653static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007654os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7655/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007656{
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 if (tcsetpgrp(fd, pgid) < 0)
7658 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007659 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007660}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007662
Guido van Rossum687dd131993-05-17 08:34:16 +00007663/* Functions acting on file descriptors */
7664
Victor Stinnerdaf45552013-08-28 00:53:59 +02007665#ifdef O_CLOEXEC
7666extern int _Py_open_cloexec_works;
7667#endif
7668
Larry Hastings2f936352014-08-05 14:04:04 +10007669
7670/*[clinic input]
7671os.open -> int
7672 path: path_t
7673 flags: int
7674 mode: int = 0o777
7675 *
7676 dir_fd: dir_fd(requires='openat') = None
7677
7678# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7679
7680Open a file for low level IO. Returns a file descriptor (integer).
7681
7682If dir_fd is not None, it should be a file descriptor open to a directory,
7683 and path should be relative; path will then be relative to that directory.
7684dir_fd may not be implemented on your platform.
7685 If it is unavailable, using it will raise a NotImplementedError.
7686[clinic start generated code]*/
7687
Larry Hastings2f936352014-08-05 14:04:04 +10007688static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007689os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7690/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007691{
7692 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007693 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007694
Victor Stinnerdaf45552013-08-28 00:53:59 +02007695#ifdef O_CLOEXEC
7696 int *atomic_flag_works = &_Py_open_cloexec_works;
7697#elif !defined(MS_WINDOWS)
7698 int *atomic_flag_works = NULL;
7699#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007700
Victor Stinnerdaf45552013-08-28 00:53:59 +02007701#ifdef MS_WINDOWS
7702 flags |= O_NOINHERIT;
7703#elif defined(O_CLOEXEC)
7704 flags |= O_CLOEXEC;
7705#endif
7706
Steve Dower8fc89802015-04-12 00:26:27 -04007707 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007708 do {
7709 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007710#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007711 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007712#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007713#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007714 if (dir_fd != DEFAULT_DIR_FD)
7715 fd = openat(dir_fd, path->narrow, flags, mode);
7716 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007717#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007718 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007719#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007720 Py_END_ALLOW_THREADS
7721 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007722 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007723
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007724 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007725 if (!async_err)
7726 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007727 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007728 }
7729
Victor Stinnerdaf45552013-08-28 00:53:59 +02007730#ifndef MS_WINDOWS
7731 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7732 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007733 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007734 }
7735#endif
7736
Larry Hastings2f936352014-08-05 14:04:04 +10007737 return fd;
7738}
7739
7740
7741/*[clinic input]
7742os.close
7743
7744 fd: int
7745
7746Close a file descriptor.
7747[clinic start generated code]*/
7748
Barry Warsaw53699e91996-12-10 23:23:01 +00007749static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007750os_close_impl(PyObject *module, int fd)
7751/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007752{
Larry Hastings2f936352014-08-05 14:04:04 +10007753 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007754 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7755 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7756 * for more details.
7757 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007759 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007761 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 Py_END_ALLOW_THREADS
7763 if (res < 0)
7764 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007765 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007766}
7767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007768
Larry Hastings2f936352014-08-05 14:04:04 +10007769/*[clinic input]
7770os.closerange
7771
7772 fd_low: int
7773 fd_high: int
7774 /
7775
7776Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7777[clinic start generated code]*/
7778
Larry Hastings2f936352014-08-05 14:04:04 +10007779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007780os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7781/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007782{
7783 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007785 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007786 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007787 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007788 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 Py_END_ALLOW_THREADS
7790 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007791}
7792
7793
Larry Hastings2f936352014-08-05 14:04:04 +10007794/*[clinic input]
7795os.dup -> int
7796
7797 fd: int
7798 /
7799
7800Return a duplicate of a file descriptor.
7801[clinic start generated code]*/
7802
Larry Hastings2f936352014-08-05 14:04:04 +10007803static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007804os_dup_impl(PyObject *module, int fd)
7805/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007806{
7807 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007808}
7809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007810
Larry Hastings2f936352014-08-05 14:04:04 +10007811/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007812os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007813 fd: int
7814 fd2: int
7815 inheritable: bool=True
7816
7817Duplicate file descriptor.
7818[clinic start generated code]*/
7819
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007820static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007821os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007822/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007823{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007824 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007825#if defined(HAVE_DUP3) && \
7826 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7827 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007828 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007829#endif
7830
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007831 if (fd < 0 || fd2 < 0) {
7832 posix_error();
7833 return -1;
7834 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007835
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007836 /* dup2() can fail with EINTR if the target FD is already open, because it
7837 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7838 * upon close(), and therefore below.
7839 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840#ifdef MS_WINDOWS
7841 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007842 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007844 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007845 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007846 if (res < 0) {
7847 posix_error();
7848 return -1;
7849 }
7850 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007851
7852 /* Character files like console cannot be make non-inheritable */
7853 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7854 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007855 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007856 }
7857
7858#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7859 Py_BEGIN_ALLOW_THREADS
7860 if (!inheritable)
7861 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7862 else
7863 res = dup2(fd, fd2);
7864 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007865 if (res < 0) {
7866 posix_error();
7867 return -1;
7868 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007869
7870#else
7871
7872#ifdef HAVE_DUP3
7873 if (!inheritable && dup3_works != 0) {
7874 Py_BEGIN_ALLOW_THREADS
7875 res = dup3(fd, fd2, O_CLOEXEC);
7876 Py_END_ALLOW_THREADS
7877 if (res < 0) {
7878 if (dup3_works == -1)
7879 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007880 if (dup3_works) {
7881 posix_error();
7882 return -1;
7883 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007884 }
7885 }
7886
7887 if (inheritable || dup3_works == 0)
7888 {
7889#endif
7890 Py_BEGIN_ALLOW_THREADS
7891 res = dup2(fd, fd2);
7892 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007893 if (res < 0) {
7894 posix_error();
7895 return -1;
7896 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007897
7898 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7899 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007900 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007901 }
7902#ifdef HAVE_DUP3
7903 }
7904#endif
7905
7906#endif
7907
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007908 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007909}
7910
Larry Hastings2f936352014-08-05 14:04:04 +10007911
Ross Lagerwall7807c352011-03-17 20:20:30 +02007912#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007913/*[clinic input]
7914os.lockf
7915
7916 fd: int
7917 An open file descriptor.
7918 command: int
7919 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7920 length: Py_off_t
7921 The number of bytes to lock, starting at the current position.
7922 /
7923
7924Apply, test or remove a POSIX lock on an open file descriptor.
7925
7926[clinic start generated code]*/
7927
Larry Hastings2f936352014-08-05 14:04:04 +10007928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007929os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7930/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007931{
7932 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007933
7934 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007935 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007936 Py_END_ALLOW_THREADS
7937
7938 if (res < 0)
7939 return posix_error();
7940
7941 Py_RETURN_NONE;
7942}
Larry Hastings2f936352014-08-05 14:04:04 +10007943#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007945
Larry Hastings2f936352014-08-05 14:04:04 +10007946/*[clinic input]
7947os.lseek -> Py_off_t
7948
7949 fd: int
7950 position: Py_off_t
7951 how: int
7952 /
7953
7954Set the position of a file descriptor. Return the new position.
7955
7956Return the new cursor position in number of bytes
7957relative to the beginning of the file.
7958[clinic start generated code]*/
7959
Larry Hastings2f936352014-08-05 14:04:04 +10007960static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007961os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7962/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007963{
7964 Py_off_t result;
7965
Guido van Rossum687dd131993-05-17 08:34:16 +00007966#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7968 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007969 case 0: how = SEEK_SET; break;
7970 case 1: how = SEEK_CUR; break;
7971 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007973#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007974
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007976 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007977
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007979 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007980#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007981 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007982#else
Larry Hastings2f936352014-08-05 14:04:04 +10007983 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007984#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007985 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007987 if (result < 0)
7988 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007989
Larry Hastings2f936352014-08-05 14:04:04 +10007990 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007991}
7992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007993
Larry Hastings2f936352014-08-05 14:04:04 +10007994/*[clinic input]
7995os.read
7996 fd: int
7997 length: Py_ssize_t
7998 /
7999
8000Read from a file descriptor. Returns a bytes object.
8001[clinic start generated code]*/
8002
Larry Hastings2f936352014-08-05 14:04:04 +10008003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008004os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8005/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008006{
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 Py_ssize_t n;
8008 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008009
8010 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 errno = EINVAL;
8012 return posix_error();
8013 }
Larry Hastings2f936352014-08-05 14:04:04 +10008014
Miss Islington (bot)18f33272018-11-22 06:17:34 -08008015 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008016
8017 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 if (buffer == NULL)
8019 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008020
Victor Stinner66aab0c2015-03-19 22:53:20 +01008021 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8022 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008024 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 }
Larry Hastings2f936352014-08-05 14:04:04 +10008026
8027 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008029
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008031}
8032
Ross Lagerwall7807c352011-03-17 20:20:30 +02008033#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008034 || defined(__APPLE__))) \
8035 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8036 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8037static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008038iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008039{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008040 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008041
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 *iov = PyMem_New(struct iovec, cnt);
8043 if (*iov == NULL) {
8044 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008045 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008046 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008047
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048 *buf = PyMem_New(Py_buffer, cnt);
8049 if (*buf == NULL) {
8050 PyMem_Del(*iov);
8051 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008052 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008053 }
8054
8055 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008056 PyObject *item = PySequence_GetItem(seq, i);
8057 if (item == NULL)
8058 goto fail;
8059 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8060 Py_DECREF(item);
8061 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008062 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008063 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008065 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008067 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008068
8069fail:
8070 PyMem_Del(*iov);
8071 for (j = 0; j < i; j++) {
8072 PyBuffer_Release(&(*buf)[j]);
8073 }
8074 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008075 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008076}
8077
8078static void
8079iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8080{
8081 int i;
8082 PyMem_Del(iov);
8083 for (i = 0; i < cnt; i++) {
8084 PyBuffer_Release(&buf[i]);
8085 }
8086 PyMem_Del(buf);
8087}
8088#endif
8089
Larry Hastings2f936352014-08-05 14:04:04 +10008090
Ross Lagerwall7807c352011-03-17 20:20:30 +02008091#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008092/*[clinic input]
8093os.readv -> Py_ssize_t
8094
8095 fd: int
8096 buffers: object
8097 /
8098
8099Read from a file descriptor fd into an iterable of buffers.
8100
8101The buffers should be mutable buffers accepting bytes.
8102readv will transfer data into each buffer until it is full
8103and then move on to the next buffer in the sequence to hold
8104the rest of the data.
8105
8106readv returns the total number of bytes read,
8107which may be less than the total capacity of all the buffers.
8108[clinic start generated code]*/
8109
Larry Hastings2f936352014-08-05 14:04:04 +10008110static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008111os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8112/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008113{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008114 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008115 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008116 struct iovec *iov;
8117 Py_buffer *buf;
8118
Larry Hastings2f936352014-08-05 14:04:04 +10008119 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008120 PyErr_SetString(PyExc_TypeError,
8121 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008122 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008123 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008124
Larry Hastings2f936352014-08-05 14:04:04 +10008125 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008126 if (cnt < 0)
8127 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008128
8129 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8130 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008131
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008132 do {
8133 Py_BEGIN_ALLOW_THREADS
8134 n = readv(fd, iov, cnt);
8135 Py_END_ALLOW_THREADS
8136 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008137
8138 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008139 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008140 if (!async_err)
8141 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008142 return -1;
8143 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008144
Larry Hastings2f936352014-08-05 14:04:04 +10008145 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008146}
Larry Hastings2f936352014-08-05 14:04:04 +10008147#endif /* HAVE_READV */
8148
Ross Lagerwall7807c352011-03-17 20:20:30 +02008149
8150#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008151/*[clinic input]
8152# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8153os.pread
8154
8155 fd: int
8156 length: int
8157 offset: Py_off_t
8158 /
8159
8160Read a number of bytes from a file descriptor starting at a particular offset.
8161
8162Read length bytes from file descriptor fd, starting at offset bytes from
8163the beginning of the file. The file offset remains unchanged.
8164[clinic start generated code]*/
8165
Larry Hastings2f936352014-08-05 14:04:04 +10008166static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008167os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8168/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008169{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008170 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008171 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008172 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008173
Larry Hastings2f936352014-08-05 14:04:04 +10008174 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175 errno = EINVAL;
8176 return posix_error();
8177 }
Larry Hastings2f936352014-08-05 14:04:04 +10008178 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008179 if (buffer == NULL)
8180 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008181
8182 do {
8183 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008184 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008185 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008186 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008187 Py_END_ALLOW_THREADS
8188 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8189
Ross Lagerwall7807c352011-03-17 20:20:30 +02008190 if (n < 0) {
8191 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008192 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008193 }
Larry Hastings2f936352014-08-05 14:04:04 +10008194 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008195 _PyBytes_Resize(&buffer, n);
8196 return buffer;
8197}
Larry Hastings2f936352014-08-05 14:04:04 +10008198#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008199
Pablo Galindo4defba32018-01-27 16:16:37 +00008200#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8201/*[clinic input]
8202os.preadv -> Py_ssize_t
8203
8204 fd: int
8205 buffers: object
8206 offset: Py_off_t
8207 flags: int = 0
8208 /
8209
8210Reads from a file descriptor into a number of mutable bytes-like objects.
8211
8212Combines the functionality of readv() and pread(). As readv(), it will
8213transfer data into each buffer until it is full and then move on to the next
8214buffer in the sequence to hold the rest of the data. Its fourth argument,
8215specifies the file offset at which the input operation is to be performed. It
8216will return the total number of bytes read (which can be less than the total
8217capacity of all the objects).
8218
8219The flags argument contains a bitwise OR of zero or more of the following flags:
8220
8221- RWF_HIPRI
8222- RWF_NOWAIT
8223
8224Using non-zero flags requires Linux 4.6 or newer.
8225[clinic start generated code]*/
8226
8227static Py_ssize_t
8228os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8229 int flags)
8230/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8231{
8232 Py_ssize_t cnt, n;
8233 int async_err = 0;
8234 struct iovec *iov;
8235 Py_buffer *buf;
8236
8237 if (!PySequence_Check(buffers)) {
8238 PyErr_SetString(PyExc_TypeError,
8239 "preadv2() arg 2 must be a sequence");
8240 return -1;
8241 }
8242
8243 cnt = PySequence_Size(buffers);
8244 if (cnt < 0) {
8245 return -1;
8246 }
8247
8248#ifndef HAVE_PREADV2
8249 if(flags != 0) {
8250 argument_unavailable_error("preadv2", "flags");
8251 return -1;
8252 }
8253#endif
8254
8255 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8256 return -1;
8257 }
8258#ifdef HAVE_PREADV2
8259 do {
8260 Py_BEGIN_ALLOW_THREADS
8261 _Py_BEGIN_SUPPRESS_IPH
8262 n = preadv2(fd, iov, cnt, offset, flags);
8263 _Py_END_SUPPRESS_IPH
8264 Py_END_ALLOW_THREADS
8265 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8266#else
8267 do {
8268 Py_BEGIN_ALLOW_THREADS
8269 _Py_BEGIN_SUPPRESS_IPH
8270 n = preadv(fd, iov, cnt, offset);
8271 _Py_END_SUPPRESS_IPH
8272 Py_END_ALLOW_THREADS
8273 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8274#endif
8275
8276 iov_cleanup(iov, buf, cnt);
8277 if (n < 0) {
8278 if (!async_err) {
8279 posix_error();
8280 }
8281 return -1;
8282 }
8283
8284 return n;
8285}
8286#endif /* HAVE_PREADV */
8287
Larry Hastings2f936352014-08-05 14:04:04 +10008288
8289/*[clinic input]
8290os.write -> Py_ssize_t
8291
8292 fd: int
8293 data: Py_buffer
8294 /
8295
8296Write a bytes object to a file descriptor.
8297[clinic start generated code]*/
8298
Larry Hastings2f936352014-08-05 14:04:04 +10008299static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008300os_write_impl(PyObject *module, int fd, Py_buffer *data)
8301/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008302{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008303 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008304}
8305
8306#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008308"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008309sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008310 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008311Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008312
Larry Hastings2f936352014-08-05 14:04:04 +10008313/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314static PyObject *
8315posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8316{
8317 int in, out;
8318 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008319 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008320 off_t offset;
8321
8322#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8323#ifndef __APPLE__
8324 Py_ssize_t len;
8325#endif
8326 PyObject *headers = NULL, *trailers = NULL;
8327 Py_buffer *hbuf, *tbuf;
8328 off_t sbytes;
8329 struct sf_hdtr sf;
8330 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008331 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008332 static char *keywords[] = {"out", "in",
8333 "offset", "count",
8334 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008336 sf.headers = NULL;
8337 sf.trailers = NULL;
8338
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008339#ifdef __APPLE__
8340 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008341 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008342#else
8343 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008344 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008345#endif
8346 &headers, &trailers, &flags))
8347 return NULL;
8348 if (headers != NULL) {
8349 if (!PySequence_Check(headers)) {
8350 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008351 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008352 return NULL;
8353 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008354 Py_ssize_t i = PySequence_Size(headers);
8355 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008356 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008357 if (i > INT_MAX) {
8358 PyErr_SetString(PyExc_OverflowError,
8359 "sendfile() header is too large");
8360 return NULL;
8361 }
8362 if (i > 0) {
8363 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008364 if (iov_setup(&(sf.headers), &hbuf,
8365 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008366 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008367#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008368 for (i = 0; i < sf.hdr_cnt; i++) {
8369 Py_ssize_t blen = sf.headers[i].iov_len;
8370# define OFF_T_MAX 0x7fffffffffffffff
8371 if (sbytes >= OFF_T_MAX - blen) {
8372 PyErr_SetString(PyExc_OverflowError,
8373 "sendfile() header is too large");
8374 return NULL;
8375 }
8376 sbytes += blen;
8377 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008378#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008379 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008380 }
8381 }
8382 if (trailers != NULL) {
8383 if (!PySequence_Check(trailers)) {
8384 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008385 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008386 return NULL;
8387 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008388 Py_ssize_t i = PySequence_Size(trailers);
8389 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008390 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008391 if (i > INT_MAX) {
8392 PyErr_SetString(PyExc_OverflowError,
8393 "sendfile() trailer is too large");
8394 return NULL;
8395 }
8396 if (i > 0) {
8397 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008398 if (iov_setup(&(sf.trailers), &tbuf,
8399 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008400 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008401 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008402 }
8403 }
8404
Steve Dower8fc89802015-04-12 00:26:27 -04008405 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008406 do {
8407 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008408#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008409 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008410#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008412#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008413 Py_END_ALLOW_THREADS
8414 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008415 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008416
8417 if (sf.headers != NULL)
8418 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8419 if (sf.trailers != NULL)
8420 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8421
8422 if (ret < 0) {
8423 if ((errno == EAGAIN) || (errno == EBUSY)) {
8424 if (sbytes != 0) {
8425 // some data has been sent
8426 goto done;
8427 }
8428 else {
8429 // no data has been sent; upper application is supposed
8430 // to retry on EAGAIN or EBUSY
8431 return posix_error();
8432 }
8433 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008434 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008435 }
8436 goto done;
8437
8438done:
8439 #if !defined(HAVE_LARGEFILE_SUPPORT)
8440 return Py_BuildValue("l", sbytes);
8441 #else
8442 return Py_BuildValue("L", sbytes);
8443 #endif
8444
8445#else
8446 Py_ssize_t count;
8447 PyObject *offobj;
8448 static char *keywords[] = {"out", "in",
8449 "offset", "count", NULL};
8450 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8451 keywords, &out, &in, &offobj, &count))
8452 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008453#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008454 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008455 do {
8456 Py_BEGIN_ALLOW_THREADS
8457 ret = sendfile(out, in, NULL, count);
8458 Py_END_ALLOW_THREADS
8459 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008460 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008461 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008462 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008463 }
8464#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008465 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008466 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008467
8468 do {
8469 Py_BEGIN_ALLOW_THREADS
8470 ret = sendfile(out, in, &offset, 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 Rodolàc9c2c8b2011-02-25 14:39:16 +00008475 return Py_BuildValue("n", ret);
8476#endif
8477}
Larry Hastings2f936352014-08-05 14:04:04 +10008478#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008479
Larry Hastings2f936352014-08-05 14:04:04 +10008480
8481/*[clinic input]
8482os.fstat
8483
8484 fd : int
8485
8486Perform a stat system call on the given file descriptor.
8487
8488Like stat(), but for an open file descriptor.
8489Equivalent to os.stat(fd).
8490[clinic start generated code]*/
8491
Larry Hastings2f936352014-08-05 14:04:04 +10008492static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008493os_fstat_impl(PyObject *module, int fd)
8494/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008495{
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 STRUCT_STAT st;
8497 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008498 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008499
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008500 do {
8501 Py_BEGIN_ALLOW_THREADS
8502 res = FSTAT(fd, &st);
8503 Py_END_ALLOW_THREADS
8504 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008506#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008507 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008508#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008509 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008510#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 }
Tim Peters5aa91602002-01-30 05:46:57 +00008512
Victor Stinner4195b5c2012-02-08 23:03:19 +01008513 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008514}
8515
Larry Hastings2f936352014-08-05 14:04:04 +10008516
8517/*[clinic input]
8518os.isatty -> bool
8519 fd: int
8520 /
8521
8522Return True if the fd is connected to a terminal.
8523
8524Return True if the file descriptor is an open file descriptor
8525connected to the slave end of a terminal.
8526[clinic start generated code]*/
8527
Larry Hastings2f936352014-08-05 14:04:04 +10008528static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008529os_isatty_impl(PyObject *module, int fd)
8530/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008531{
Steve Dower8fc89802015-04-12 00:26:27 -04008532 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008533 _Py_BEGIN_SUPPRESS_IPH
8534 return_value = isatty(fd);
8535 _Py_END_SUPPRESS_IPH
8536 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008537}
8538
8539
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008540#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008541/*[clinic input]
8542os.pipe
8543
8544Create a pipe.
8545
8546Returns a tuple of two file descriptors:
8547 (read_fd, write_fd)
8548[clinic start generated code]*/
8549
Larry Hastings2f936352014-08-05 14:04:04 +10008550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008551os_pipe_impl(PyObject *module)
8552/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008553{
Victor Stinner8c62be82010-05-06 00:08:46 +00008554 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008555#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008556 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008557 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008559#else
8560 int res;
8561#endif
8562
8563#ifdef MS_WINDOWS
8564 attr.nLength = sizeof(attr);
8565 attr.lpSecurityDescriptor = NULL;
8566 attr.bInheritHandle = FALSE;
8567
8568 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008569 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008570 ok = CreatePipe(&read, &write, &attr, 0);
8571 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008572 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8573 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008574 if (fds[0] == -1 || fds[1] == -1) {
8575 CloseHandle(read);
8576 CloseHandle(write);
8577 ok = 0;
8578 }
8579 }
Steve Dowerc3630612016-11-19 18:41:16 -08008580 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008581 Py_END_ALLOW_THREADS
8582
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008584 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008585#else
8586
8587#ifdef HAVE_PIPE2
8588 Py_BEGIN_ALLOW_THREADS
8589 res = pipe2(fds, O_CLOEXEC);
8590 Py_END_ALLOW_THREADS
8591
8592 if (res != 0 && errno == ENOSYS)
8593 {
8594#endif
8595 Py_BEGIN_ALLOW_THREADS
8596 res = pipe(fds);
8597 Py_END_ALLOW_THREADS
8598
8599 if (res == 0) {
8600 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8601 close(fds[0]);
8602 close(fds[1]);
8603 return NULL;
8604 }
8605 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8606 close(fds[0]);
8607 close(fds[1]);
8608 return NULL;
8609 }
8610 }
8611#ifdef HAVE_PIPE2
8612 }
8613#endif
8614
8615 if (res != 0)
8616 return PyErr_SetFromErrno(PyExc_OSError);
8617#endif /* !MS_WINDOWS */
8618 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008619}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008620#endif /* HAVE_PIPE */
8621
Larry Hastings2f936352014-08-05 14:04:04 +10008622
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008623#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008624/*[clinic input]
8625os.pipe2
8626
8627 flags: int
8628 /
8629
8630Create a pipe with flags set atomically.
8631
8632Returns a tuple of two file descriptors:
8633 (read_fd, write_fd)
8634
8635flags can be constructed by ORing together one or more of these values:
8636O_NONBLOCK, O_CLOEXEC.
8637[clinic start generated code]*/
8638
Larry Hastings2f936352014-08-05 14:04:04 +10008639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008640os_pipe2_impl(PyObject *module, int flags)
8641/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008642{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008643 int fds[2];
8644 int res;
8645
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008646 res = pipe2(fds, flags);
8647 if (res != 0)
8648 return posix_error();
8649 return Py_BuildValue("(ii)", fds[0], fds[1]);
8650}
8651#endif /* HAVE_PIPE2 */
8652
Larry Hastings2f936352014-08-05 14:04:04 +10008653
Ross Lagerwall7807c352011-03-17 20:20:30 +02008654#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008655/*[clinic input]
8656os.writev -> Py_ssize_t
8657 fd: int
8658 buffers: object
8659 /
8660
8661Iterate over buffers, and write the contents of each to a file descriptor.
8662
8663Returns the total number of bytes written.
8664buffers must be a sequence of bytes-like objects.
8665[clinic start generated code]*/
8666
Larry Hastings2f936352014-08-05 14:04:04 +10008667static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008668os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8669/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008670{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008671 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008672 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008673 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008674 struct iovec *iov;
8675 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008676
8677 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008678 PyErr_SetString(PyExc_TypeError,
8679 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008680 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008681 }
Larry Hastings2f936352014-08-05 14:04:04 +10008682 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008683 if (cnt < 0)
8684 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008685
Larry Hastings2f936352014-08-05 14:04:04 +10008686 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8687 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008688 }
8689
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008690 do {
8691 Py_BEGIN_ALLOW_THREADS
8692 result = writev(fd, iov, cnt);
8693 Py_END_ALLOW_THREADS
8694 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008695
8696 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008697 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008698 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008699
Georg Brandl306336b2012-06-24 12:55:33 +02008700 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008701}
Larry Hastings2f936352014-08-05 14:04:04 +10008702#endif /* HAVE_WRITEV */
8703
8704
8705#ifdef HAVE_PWRITE
8706/*[clinic input]
8707os.pwrite -> Py_ssize_t
8708
8709 fd: int
8710 buffer: Py_buffer
8711 offset: Py_off_t
8712 /
8713
8714Write bytes to a file descriptor starting at a particular offset.
8715
8716Write buffer to fd, starting at offset bytes from the beginning of
8717the file. Returns the number of bytes writte. Does not change the
8718current file offset.
8719[clinic start generated code]*/
8720
Larry Hastings2f936352014-08-05 14:04:04 +10008721static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008722os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8723/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008724{
8725 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008726 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008727
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008728 do {
8729 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008730 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008731 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008732 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008733 Py_END_ALLOW_THREADS
8734 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008735
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008736 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008737 posix_error();
8738 return size;
8739}
8740#endif /* HAVE_PWRITE */
8741
Pablo Galindo4defba32018-01-27 16:16:37 +00008742#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8743/*[clinic input]
8744os.pwritev -> Py_ssize_t
8745
8746 fd: int
8747 buffers: object
8748 offset: Py_off_t
8749 flags: int = 0
8750 /
8751
8752Writes the contents of bytes-like objects to a file descriptor at a given offset.
8753
8754Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8755of bytes-like objects. Buffers are processed in array order. Entire contents of first
8756buffer is written before proceeding to second, and so on. The operating system may
8757set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8758This function writes the contents of each object to the file descriptor and returns
8759the total number of bytes written.
8760
8761The flags argument contains a bitwise OR of zero or more of the following flags:
8762
8763- RWF_DSYNC
8764- RWF_SYNC
8765
8766Using non-zero flags requires Linux 4.7 or newer.
8767[clinic start generated code]*/
8768
8769static Py_ssize_t
8770os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8771 int flags)
8772/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8773{
8774 Py_ssize_t cnt;
8775 Py_ssize_t result;
8776 int async_err = 0;
8777 struct iovec *iov;
8778 Py_buffer *buf;
8779
8780 if (!PySequence_Check(buffers)) {
8781 PyErr_SetString(PyExc_TypeError,
8782 "pwritev() arg 2 must be a sequence");
8783 return -1;
8784 }
8785
8786 cnt = PySequence_Size(buffers);
8787 if (cnt < 0) {
8788 return -1;
8789 }
8790
8791#ifndef HAVE_PWRITEV2
8792 if(flags != 0) {
8793 argument_unavailable_error("pwritev2", "flags");
8794 return -1;
8795 }
8796#endif
8797
8798 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8799 return -1;
8800 }
8801#ifdef HAVE_PWRITEV2
8802 do {
8803 Py_BEGIN_ALLOW_THREADS
8804 _Py_BEGIN_SUPPRESS_IPH
8805 result = pwritev2(fd, iov, cnt, offset, flags);
8806 _Py_END_SUPPRESS_IPH
8807 Py_END_ALLOW_THREADS
8808 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8809#else
8810 do {
8811 Py_BEGIN_ALLOW_THREADS
8812 _Py_BEGIN_SUPPRESS_IPH
8813 result = pwritev(fd, iov, cnt, offset);
8814 _Py_END_SUPPRESS_IPH
8815 Py_END_ALLOW_THREADS
8816 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8817#endif
8818
8819 iov_cleanup(iov, buf, cnt);
8820 if (result < 0) {
8821 if (!async_err) {
8822 posix_error();
8823 }
8824 return -1;
8825 }
8826
8827 return result;
8828}
8829#endif /* HAVE_PWRITEV */
8830
8831
8832
Larry Hastings2f936352014-08-05 14:04:04 +10008833
8834#ifdef HAVE_MKFIFO
8835/*[clinic input]
8836os.mkfifo
8837
8838 path: path_t
8839 mode: int=0o666
8840 *
8841 dir_fd: dir_fd(requires='mkfifoat')=None
8842
8843Create a "fifo" (a POSIX named pipe).
8844
8845If dir_fd is not None, it should be a file descriptor open to a directory,
8846 and path should be relative; path will then be relative to that directory.
8847dir_fd may not be implemented on your platform.
8848 If it is unavailable, using it will raise a NotImplementedError.
8849[clinic start generated code]*/
8850
Larry Hastings2f936352014-08-05 14:04:04 +10008851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008852os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8853/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008854{
8855 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008856 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008857
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008858 do {
8859 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008860#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008861 if (dir_fd != DEFAULT_DIR_FD)
8862 result = mkfifoat(dir_fd, path->narrow, mode);
8863 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008864#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008865 result = mkfifo(path->narrow, mode);
8866 Py_END_ALLOW_THREADS
8867 } while (result != 0 && errno == EINTR &&
8868 !(async_err = PyErr_CheckSignals()));
8869 if (result != 0)
8870 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008871
8872 Py_RETURN_NONE;
8873}
8874#endif /* HAVE_MKFIFO */
8875
8876
8877#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8878/*[clinic input]
8879os.mknod
8880
8881 path: path_t
8882 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008883 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008884 *
8885 dir_fd: dir_fd(requires='mknodat')=None
8886
8887Create a node in the file system.
8888
8889Create a node in the file system (file, device special file or named pipe)
8890at path. mode specifies both the permissions to use and the
8891type of node to be created, being combined (bitwise OR) with one of
8892S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8893device defines the newly created device special file (probably using
8894os.makedev()). Otherwise device is ignored.
8895
8896If dir_fd is not None, it should be a file descriptor open to a directory,
8897 and path should be relative; path will then be relative to that directory.
8898dir_fd may not be implemented on your platform.
8899 If it is unavailable, using it will raise a NotImplementedError.
8900[clinic start generated code]*/
8901
Larry Hastings2f936352014-08-05 14:04:04 +10008902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008903os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008904 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008905/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008906{
8907 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008908 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008909
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008910 do {
8911 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008912#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008913 if (dir_fd != DEFAULT_DIR_FD)
8914 result = mknodat(dir_fd, path->narrow, mode, device);
8915 else
Larry Hastings2f936352014-08-05 14:04:04 +10008916#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008917 result = mknod(path->narrow, mode, device);
8918 Py_END_ALLOW_THREADS
8919 } while (result != 0 && errno == EINTR &&
8920 !(async_err = PyErr_CheckSignals()));
8921 if (result != 0)
8922 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008923
8924 Py_RETURN_NONE;
8925}
8926#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8927
8928
8929#ifdef HAVE_DEVICE_MACROS
8930/*[clinic input]
8931os.major -> unsigned_int
8932
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008933 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008934 /
8935
8936Extracts a device major number from a raw device number.
8937[clinic start generated code]*/
8938
Larry Hastings2f936352014-08-05 14:04:04 +10008939static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008940os_major_impl(PyObject *module, dev_t device)
8941/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008942{
8943 return major(device);
8944}
8945
8946
8947/*[clinic input]
8948os.minor -> unsigned_int
8949
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008950 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008951 /
8952
8953Extracts a device minor number from a raw device number.
8954[clinic start generated code]*/
8955
Larry Hastings2f936352014-08-05 14:04:04 +10008956static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008957os_minor_impl(PyObject *module, dev_t device)
8958/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008959{
8960 return minor(device);
8961}
8962
8963
8964/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008965os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008966
8967 major: int
8968 minor: int
8969 /
8970
8971Composes a raw device number from the major and minor device numbers.
8972[clinic start generated code]*/
8973
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008974static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008975os_makedev_impl(PyObject *module, int major, int minor)
8976/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008977{
8978 return makedev(major, minor);
8979}
8980#endif /* HAVE_DEVICE_MACROS */
8981
8982
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008983#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008984/*[clinic input]
8985os.ftruncate
8986
8987 fd: int
8988 length: Py_off_t
8989 /
8990
8991Truncate a file, specified by file descriptor, to a specific length.
8992[clinic start generated code]*/
8993
Larry Hastings2f936352014-08-05 14:04:04 +10008994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008995os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8996/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008997{
8998 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008999 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009000
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009001 do {
9002 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009003 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009004#ifdef MS_WINDOWS
9005 result = _chsize_s(fd, length);
9006#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009007 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009008#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009009 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009010 Py_END_ALLOW_THREADS
9011 } while (result != 0 && errno == EINTR &&
9012 !(async_err = PyErr_CheckSignals()));
9013 if (result != 0)
9014 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009015 Py_RETURN_NONE;
9016}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009017#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009018
9019
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009020#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009021/*[clinic input]
9022os.truncate
9023 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9024 length: Py_off_t
9025
9026Truncate a file, specified by path, to a specific length.
9027
9028On some platforms, path may also be specified as an open file descriptor.
9029 If this functionality is unavailable, using it raises an exception.
9030[clinic start generated code]*/
9031
Larry Hastings2f936352014-08-05 14:04:04 +10009032static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009033os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9034/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009035{
9036 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009037#ifdef MS_WINDOWS
9038 int fd;
9039#endif
9040
9041 if (path->fd != -1)
9042 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009043
9044 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009045 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009046#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009047 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009048 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009049 result = -1;
9050 else {
9051 result = _chsize_s(fd, length);
9052 close(fd);
9053 if (result < 0)
9054 errno = result;
9055 }
9056#else
9057 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009058#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009059 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009060 Py_END_ALLOW_THREADS
9061 if (result < 0)
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07009062 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009063
9064 Py_RETURN_NONE;
9065}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009066#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009067
Ross Lagerwall7807c352011-03-17 20:20:30 +02009068
Victor Stinnerd6b17692014-09-30 12:20:05 +02009069/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9070 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9071 defined, which is the case in Python on AIX. AIX bug report:
9072 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9073#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9074# define POSIX_FADVISE_AIX_BUG
9075#endif
9076
Victor Stinnerec39e262014-09-30 12:35:58 +02009077
Victor Stinnerd6b17692014-09-30 12:20:05 +02009078#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009079/*[clinic input]
9080os.posix_fallocate
9081
9082 fd: int
9083 offset: Py_off_t
9084 length: Py_off_t
9085 /
9086
9087Ensure a file has allocated at least a particular number of bytes on disk.
9088
9089Ensure that the file specified by fd encompasses a range of bytes
9090starting at offset bytes from the beginning and continuing for length bytes.
9091[clinic start generated code]*/
9092
Larry Hastings2f936352014-08-05 14:04:04 +10009093static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009094os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009095 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009096/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009097{
9098 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009099 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009100
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009101 do {
9102 Py_BEGIN_ALLOW_THREADS
9103 result = posix_fallocate(fd, offset, length);
9104 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009105 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9106
9107 if (result == 0)
9108 Py_RETURN_NONE;
9109
9110 if (async_err)
9111 return NULL;
9112
9113 errno = result;
9114 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009115}
Victor Stinnerec39e262014-09-30 12:35:58 +02009116#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009117
Ross Lagerwall7807c352011-03-17 20:20:30 +02009118
Victor Stinnerd6b17692014-09-30 12:20:05 +02009119#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009120/*[clinic input]
9121os.posix_fadvise
9122
9123 fd: int
9124 offset: Py_off_t
9125 length: Py_off_t
9126 advice: int
9127 /
9128
9129Announce an intention to access data in a specific pattern.
9130
9131Announce an intention to access data in a specific pattern, thus allowing
9132the kernel to make optimizations.
9133The advice applies to the region of the file specified by fd starting at
9134offset and continuing for length bytes.
9135advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9136POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9137POSIX_FADV_DONTNEED.
9138[clinic start generated code]*/
9139
Larry Hastings2f936352014-08-05 14:04:04 +10009140static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009141os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009142 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009143/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009144{
9145 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009146 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009147
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009148 do {
9149 Py_BEGIN_ALLOW_THREADS
9150 result = posix_fadvise(fd, offset, length, advice);
9151 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009152 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9153
9154 if (result == 0)
9155 Py_RETURN_NONE;
9156
9157 if (async_err)
9158 return NULL;
9159
9160 errno = result;
9161 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009162}
Victor Stinnerec39e262014-09-30 12:35:58 +02009163#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009164
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009165#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009166
Fred Drake762e2061999-08-26 17:23:54 +00009167/* Save putenv() parameters as values here, so we can collect them when they
9168 * get re-set with another call for the same key. */
9169static PyObject *posix_putenv_garbage;
9170
Larry Hastings2f936352014-08-05 14:04:04 +10009171static void
9172posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009173{
Larry Hastings2f936352014-08-05 14:04:04 +10009174 /* Install the first arg and newstr in posix_putenv_garbage;
9175 * this will cause previous value to be collected. This has to
9176 * happen after the real putenv() call because the old value
9177 * was still accessible until then. */
9178 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9179 /* really not much we can do; just leak */
9180 PyErr_Clear();
9181 else
9182 Py_DECREF(value);
9183}
9184
9185
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009186#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009187/*[clinic input]
9188os.putenv
9189
9190 name: unicode
9191 value: unicode
9192 /
9193
9194Change or add an environment variable.
9195[clinic start generated code]*/
9196
Larry Hastings2f936352014-08-05 14:04:04 +10009197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009198os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9199/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009200{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009201 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009202 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009203
Serhiy Storchaka77703942017-06-25 07:33:01 +03009204 /* Search from index 1 because on Windows starting '=' is allowed for
9205 defining hidden environment variables. */
9206 if (PyUnicode_GET_LENGTH(name) == 0 ||
9207 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9208 {
9209 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9210 return NULL;
9211 }
Larry Hastings2f936352014-08-05 14:04:04 +10009212 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9213 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009214 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009215 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009216
9217 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9218 if (env == NULL)
9219 goto error;
9220 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009221 PyErr_Format(PyExc_ValueError,
9222 "the environment variable is longer than %u characters",
9223 _MAX_ENV);
9224 goto error;
9225 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009226 if (wcslen(env) != (size_t)size) {
9227 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009228 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009229 }
9230
Larry Hastings2f936352014-08-05 14:04:04 +10009231 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009232 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009233 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009234 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009235
Larry Hastings2f936352014-08-05 14:04:04 +10009236 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009237 Py_RETURN_NONE;
9238
9239error:
Larry Hastings2f936352014-08-05 14:04:04 +10009240 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009241 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009242}
Larry Hastings2f936352014-08-05 14:04:04 +10009243#else /* MS_WINDOWS */
9244/*[clinic input]
9245os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009246
Larry Hastings2f936352014-08-05 14:04:04 +10009247 name: FSConverter
9248 value: FSConverter
9249 /
9250
9251Change or add an environment variable.
9252[clinic start generated code]*/
9253
Larry Hastings2f936352014-08-05 14:04:04 +10009254static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009255os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9256/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009257{
9258 PyObject *bytes = NULL;
9259 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009260 const char *name_string = PyBytes_AS_STRING(name);
9261 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009262
Serhiy Storchaka77703942017-06-25 07:33:01 +03009263 if (strchr(name_string, '=') != NULL) {
9264 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9265 return NULL;
9266 }
Larry Hastings2f936352014-08-05 14:04:04 +10009267 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9268 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009269 return NULL;
9270 }
9271
9272 env = PyBytes_AS_STRING(bytes);
9273 if (putenv(env)) {
9274 Py_DECREF(bytes);
9275 return posix_error();
9276 }
9277
9278 posix_putenv_garbage_setitem(name, bytes);
9279 Py_RETURN_NONE;
9280}
9281#endif /* MS_WINDOWS */
9282#endif /* HAVE_PUTENV */
9283
9284
9285#ifdef HAVE_UNSETENV
9286/*[clinic input]
9287os.unsetenv
9288 name: FSConverter
9289 /
9290
9291Delete an environment variable.
9292[clinic start generated code]*/
9293
Larry Hastings2f936352014-08-05 14:04:04 +10009294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009295os_unsetenv_impl(PyObject *module, PyObject *name)
9296/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009297{
Victor Stinner984890f2011-11-24 13:53:38 +01009298#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009299 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009300#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009301
Victor Stinner984890f2011-11-24 13:53:38 +01009302#ifdef HAVE_BROKEN_UNSETENV
9303 unsetenv(PyBytes_AS_STRING(name));
9304#else
Victor Stinner65170952011-11-22 22:16:17 +01009305 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009306 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009307 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009308#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009309
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 /* Remove the key from posix_putenv_garbage;
9311 * this will cause it to be collected. This has to
9312 * happen after the real unsetenv() call because the
9313 * old value was still accessible until then.
9314 */
Victor Stinner65170952011-11-22 22:16:17 +01009315 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 /* really not much we can do; just leak */
9317 PyErr_Clear();
9318 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009319 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009320}
Larry Hastings2f936352014-08-05 14:04:04 +10009321#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009322
Larry Hastings2f936352014-08-05 14:04:04 +10009323
9324/*[clinic input]
9325os.strerror
9326
9327 code: int
9328 /
9329
9330Translate an error code to a message string.
9331[clinic start generated code]*/
9332
Larry Hastings2f936352014-08-05 14:04:04 +10009333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009334os_strerror_impl(PyObject *module, int code)
9335/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009336{
9337 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 if (message == NULL) {
9339 PyErr_SetString(PyExc_ValueError,
9340 "strerror() argument out of range");
9341 return NULL;
9342 }
Victor Stinner1b579672011-12-17 05:47:23 +01009343 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009344}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009345
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009346
Guido van Rossumc9641791998-08-04 15:26:23 +00009347#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009348#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009349/*[clinic input]
9350os.WCOREDUMP -> bool
9351
9352 status: int
9353 /
9354
9355Return True if the process returning status was dumped to a core file.
9356[clinic start generated code]*/
9357
Larry Hastings2f936352014-08-05 14:04:04 +10009358static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009359os_WCOREDUMP_impl(PyObject *module, int status)
9360/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009361{
9362 WAIT_TYPE wait_status;
9363 WAIT_STATUS_INT(wait_status) = status;
9364 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009365}
9366#endif /* WCOREDUMP */
9367
Larry Hastings2f936352014-08-05 14:04:04 +10009368
Fred Drake106c1a02002-04-23 15:58:02 +00009369#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009370/*[clinic input]
9371os.WIFCONTINUED -> bool
9372
9373 status: int
9374
9375Return True if a particular process was continued from a job control stop.
9376
9377Return True if the process returning status was continued from a
9378job control stop.
9379[clinic start generated code]*/
9380
Larry Hastings2f936352014-08-05 14:04:04 +10009381static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009382os_WIFCONTINUED_impl(PyObject *module, int status)
9383/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009384{
9385 WAIT_TYPE wait_status;
9386 WAIT_STATUS_INT(wait_status) = status;
9387 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009388}
9389#endif /* WIFCONTINUED */
9390
Larry Hastings2f936352014-08-05 14:04:04 +10009391
Guido van Rossumc9641791998-08-04 15:26:23 +00009392#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009393/*[clinic input]
9394os.WIFSTOPPED -> bool
9395
9396 status: int
9397
9398Return True if the process returning status was stopped.
9399[clinic start generated code]*/
9400
Larry Hastings2f936352014-08-05 14:04:04 +10009401static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009402os_WIFSTOPPED_impl(PyObject *module, int status)
9403/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009404{
9405 WAIT_TYPE wait_status;
9406 WAIT_STATUS_INT(wait_status) = status;
9407 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009408}
9409#endif /* WIFSTOPPED */
9410
Larry Hastings2f936352014-08-05 14:04:04 +10009411
Guido van Rossumc9641791998-08-04 15:26:23 +00009412#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009413/*[clinic input]
9414os.WIFSIGNALED -> bool
9415
9416 status: int
9417
9418Return True if the process returning status was terminated by a signal.
9419[clinic start generated code]*/
9420
Larry Hastings2f936352014-08-05 14:04:04 +10009421static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009422os_WIFSIGNALED_impl(PyObject *module, int status)
9423/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009424{
9425 WAIT_TYPE wait_status;
9426 WAIT_STATUS_INT(wait_status) = status;
9427 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009428}
9429#endif /* WIFSIGNALED */
9430
Larry Hastings2f936352014-08-05 14:04:04 +10009431
Guido van Rossumc9641791998-08-04 15:26:23 +00009432#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009433/*[clinic input]
9434os.WIFEXITED -> bool
9435
9436 status: int
9437
9438Return True if the process returning status exited via the exit() system call.
9439[clinic start generated code]*/
9440
Larry Hastings2f936352014-08-05 14:04:04 +10009441static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009442os_WIFEXITED_impl(PyObject *module, int status)
9443/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009444{
9445 WAIT_TYPE wait_status;
9446 WAIT_STATUS_INT(wait_status) = status;
9447 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009448}
9449#endif /* WIFEXITED */
9450
Larry Hastings2f936352014-08-05 14:04:04 +10009451
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009452#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009453/*[clinic input]
9454os.WEXITSTATUS -> int
9455
9456 status: int
9457
9458Return the process return code from status.
9459[clinic start generated code]*/
9460
Larry Hastings2f936352014-08-05 14:04:04 +10009461static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009462os_WEXITSTATUS_impl(PyObject *module, int status)
9463/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009464{
9465 WAIT_TYPE wait_status;
9466 WAIT_STATUS_INT(wait_status) = status;
9467 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009468}
9469#endif /* WEXITSTATUS */
9470
Larry Hastings2f936352014-08-05 14:04:04 +10009471
Guido van Rossumc9641791998-08-04 15:26:23 +00009472#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009473/*[clinic input]
9474os.WTERMSIG -> int
9475
9476 status: int
9477
9478Return the signal that terminated the process that provided the status value.
9479[clinic start generated code]*/
9480
Larry Hastings2f936352014-08-05 14:04:04 +10009481static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009482os_WTERMSIG_impl(PyObject *module, int status)
9483/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009484{
9485 WAIT_TYPE wait_status;
9486 WAIT_STATUS_INT(wait_status) = status;
9487 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009488}
9489#endif /* WTERMSIG */
9490
Larry Hastings2f936352014-08-05 14:04:04 +10009491
Guido van Rossumc9641791998-08-04 15:26:23 +00009492#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009493/*[clinic input]
9494os.WSTOPSIG -> int
9495
9496 status: int
9497
9498Return the signal that stopped the process that provided the status value.
9499[clinic start generated code]*/
9500
Larry Hastings2f936352014-08-05 14:04:04 +10009501static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009502os_WSTOPSIG_impl(PyObject *module, int status)
9503/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009504{
9505 WAIT_TYPE wait_status;
9506 WAIT_STATUS_INT(wait_status) = status;
9507 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009508}
9509#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009510#endif /* HAVE_SYS_WAIT_H */
9511
9512
Thomas Wouters477c8d52006-05-27 19:21:47 +00009513#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009514#ifdef _SCO_DS
9515/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9516 needed definitions in sys/statvfs.h */
9517#define _SVID3
9518#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009519#include <sys/statvfs.h>
9520
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009521static PyObject*
9522_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9524 if (v == NULL)
9525 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009526
9527#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9529 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9530 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9531 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9532 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9533 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9534 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9535 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9536 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9537 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009538#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9540 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9541 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009542 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009544 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009546 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009548 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009550 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009552 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9554 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009555#endif
Michael Felt502d5512018-01-05 13:01:58 +01009556/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9557 * (issue #32390). */
9558#if defined(_AIX) && defined(_ALL_SOURCE)
9559 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9560#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009561 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009562#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009563 if (PyErr_Occurred()) {
9564 Py_DECREF(v);
9565 return NULL;
9566 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009567
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009569}
9570
Larry Hastings2f936352014-08-05 14:04:04 +10009571
9572/*[clinic input]
9573os.fstatvfs
9574 fd: int
9575 /
9576
9577Perform an fstatvfs system call on the given fd.
9578
9579Equivalent to statvfs(fd).
9580[clinic start generated code]*/
9581
Larry Hastings2f936352014-08-05 14:04:04 +10009582static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009583os_fstatvfs_impl(PyObject *module, int fd)
9584/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009585{
9586 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009587 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009589
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009590 do {
9591 Py_BEGIN_ALLOW_THREADS
9592 result = fstatvfs(fd, &st);
9593 Py_END_ALLOW_THREADS
9594 } while (result != 0 && errno == EINTR &&
9595 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009596 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009597 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009598
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009600}
Larry Hastings2f936352014-08-05 14:04:04 +10009601#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009602
9603
Thomas Wouters477c8d52006-05-27 19:21:47 +00009604#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009605#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009606/*[clinic input]
9607os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009608
Larry Hastings2f936352014-08-05 14:04:04 +10009609 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9610
9611Perform a statvfs system call on the given path.
9612
9613path may always be specified as a string.
9614On some platforms, path may also be specified as an open file descriptor.
9615 If this functionality is unavailable, using it raises an exception.
9616[clinic start generated code]*/
9617
Larry Hastings2f936352014-08-05 14:04:04 +10009618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009619os_statvfs_impl(PyObject *module, path_t *path)
9620/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009621{
9622 int result;
9623 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009624
9625 Py_BEGIN_ALLOW_THREADS
9626#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009627 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009628#ifdef __APPLE__
9629 /* handle weak-linking on Mac OS X 10.3 */
9630 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009631 fd_specified("statvfs", path->fd);
9632 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009633 }
9634#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009635 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009636 }
9637 else
9638#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009639 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009640 Py_END_ALLOW_THREADS
9641
9642 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009643 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009644 }
9645
Larry Hastings2f936352014-08-05 14:04:04 +10009646 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009647}
Larry Hastings2f936352014-08-05 14:04:04 +10009648#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9649
Guido van Rossum94f6f721999-01-06 18:42:14 +00009650
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009651#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009652/*[clinic input]
9653os._getdiskusage
9654
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009655 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009656
9657Return disk usage statistics about the given path as a (total, free) tuple.
9658[clinic start generated code]*/
9659
Larry Hastings2f936352014-08-05 14:04:04 +10009660static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009661os__getdiskusage_impl(PyObject *module, path_t *path)
9662/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009663{
9664 BOOL retval;
9665 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009666
9667 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009668 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009669 Py_END_ALLOW_THREADS
9670 if (retval == 0)
9671 return PyErr_SetFromWindowsErr(0);
9672
9673 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9674}
Larry Hastings2f936352014-08-05 14:04:04 +10009675#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009676
9677
Fred Drakec9680921999-12-13 16:37:25 +00009678/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9679 * It maps strings representing configuration variable names to
9680 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009681 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009682 * rarely-used constants. There are three separate tables that use
9683 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009684 *
9685 * This code is always included, even if none of the interfaces that
9686 * need it are included. The #if hackery needed to avoid it would be
9687 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009688 */
9689struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009690 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009691 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009692};
9693
Fred Drake12c6e2d1999-12-14 21:25:03 +00009694static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009695conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009696 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009697{
Christian Heimes217cfd12007-12-02 14:31:20 +00009698 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009699 int value = _PyLong_AsInt(arg);
9700 if (value == -1 && PyErr_Occurred())
9701 return 0;
9702 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009703 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009704 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009705 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009706 /* look up the value in the table using a binary search */
9707 size_t lo = 0;
9708 size_t mid;
9709 size_t hi = tablesize;
9710 int cmp;
9711 const char *confname;
9712 if (!PyUnicode_Check(arg)) {
9713 PyErr_SetString(PyExc_TypeError,
9714 "configuration names must be strings or integers");
9715 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009717 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009718 if (confname == NULL)
9719 return 0;
9720 while (lo < hi) {
9721 mid = (lo + hi) / 2;
9722 cmp = strcmp(confname, table[mid].name);
9723 if (cmp < 0)
9724 hi = mid;
9725 else if (cmp > 0)
9726 lo = mid + 1;
9727 else {
9728 *valuep = table[mid].value;
9729 return 1;
9730 }
9731 }
9732 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9733 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009735}
9736
9737
9738#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9739static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009740#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009742#endif
9743#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009745#endif
Fred Drakec9680921999-12-13 16:37:25 +00009746#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009791#ifdef _PC_ACL_ENABLED
9792 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9793#endif
9794#ifdef _PC_MIN_HOLE_SIZE
9795 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9796#endif
9797#ifdef _PC_ALLOC_SIZE_MIN
9798 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9799#endif
9800#ifdef _PC_REC_INCR_XFER_SIZE
9801 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9802#endif
9803#ifdef _PC_REC_MAX_XFER_SIZE
9804 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9805#endif
9806#ifdef _PC_REC_MIN_XFER_SIZE
9807 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9808#endif
9809#ifdef _PC_REC_XFER_ALIGN
9810 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9811#endif
9812#ifdef _PC_SYMLINK_MAX
9813 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9814#endif
9815#ifdef _PC_XATTR_ENABLED
9816 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9817#endif
9818#ifdef _PC_XATTR_EXISTS
9819 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9820#endif
9821#ifdef _PC_TIMESTAMP_RESOLUTION
9822 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9823#endif
Fred Drakec9680921999-12-13 16:37:25 +00009824};
9825
Fred Drakec9680921999-12-13 16:37:25 +00009826static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009827conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009828{
9829 return conv_confname(arg, valuep, posix_constants_pathconf,
9830 sizeof(posix_constants_pathconf)
9831 / sizeof(struct constdef));
9832}
9833#endif
9834
Larry Hastings2f936352014-08-05 14:04:04 +10009835
Fred Drakec9680921999-12-13 16:37:25 +00009836#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009837/*[clinic input]
9838os.fpathconf -> long
9839
9840 fd: int
9841 name: path_confname
9842 /
9843
9844Return the configuration limit name for the file descriptor fd.
9845
9846If there is no limit, return -1.
9847[clinic start generated code]*/
9848
Larry Hastings2f936352014-08-05 14:04:04 +10009849static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009850os_fpathconf_impl(PyObject *module, int fd, int name)
9851/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009852{
9853 long limit;
9854
9855 errno = 0;
9856 limit = fpathconf(fd, name);
9857 if (limit == -1 && errno != 0)
9858 posix_error();
9859
9860 return limit;
9861}
9862#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009863
9864
9865#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009866/*[clinic input]
9867os.pathconf -> long
9868 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9869 name: path_confname
9870
9871Return the configuration limit name for the file or directory path.
9872
9873If there is no limit, return -1.
9874On some platforms, path may also be specified as an open file descriptor.
9875 If this functionality is unavailable, using it raises an exception.
9876[clinic start generated code]*/
9877
Larry Hastings2f936352014-08-05 14:04:04 +10009878static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009879os_pathconf_impl(PyObject *module, path_t *path, int name)
9880/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009881{
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009883
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009885#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009886 if (path->fd != -1)
9887 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009888 else
9889#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009890 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 if (limit == -1 && errno != 0) {
9892 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009893 /* could be a path or name problem */
9894 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009895 else
Larry Hastings2f936352014-08-05 14:04:04 +10009896 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 }
Larry Hastings2f936352014-08-05 14:04:04 +10009898
9899 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009900}
Larry Hastings2f936352014-08-05 14:04:04 +10009901#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009902
9903#ifdef HAVE_CONFSTR
9904static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009905#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009907#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009908#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009910#endif
9911#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009913#endif
Fred Draked86ed291999-12-15 15:34:33 +00009914#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009916#endif
9917#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009919#endif
9920#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009922#endif
9923#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009925#endif
Fred Drakec9680921999-12-13 16:37:25 +00009926#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
Fred Draked86ed291999-12-15 15:34:33 +00009950#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009952#endif
Fred Drakec9680921999-12-13 16:37:25 +00009953#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
Fred Draked86ed291999-12-15 15:34:33 +00009956#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009958#endif
9959#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009961#endif
9962#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009964#endif
9965#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009967#endif
Fred Drakec9680921999-12-13 16:37:25 +00009968#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
Fred Draked86ed291999-12-15 15:34:33 +000010016#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010018#endif
10019#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010021#endif
10022#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010024#endif
10025#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010027#endif
10028#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010030#endif
10031#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010033#endif
10034#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010036#endif
10037#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010039#endif
10040#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010042#endif
10043#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010045#endif
10046#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010048#endif
10049#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010051#endif
10052#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010054#endif
Fred Drakec9680921999-12-13 16:37:25 +000010055};
10056
10057static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010058conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010059{
10060 return conv_confname(arg, valuep, posix_constants_confstr,
10061 sizeof(posix_constants_confstr)
10062 / sizeof(struct constdef));
10063}
10064
Larry Hastings2f936352014-08-05 14:04:04 +100010065
10066/*[clinic input]
10067os.confstr
10068
10069 name: confstr_confname
10070 /
10071
10072Return a string-valued system configuration variable.
10073[clinic start generated code]*/
10074
Larry Hastings2f936352014-08-05 14:04:04 +100010075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010076os_confstr_impl(PyObject *module, int name)
10077/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010078{
10079 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010080 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010081 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010082
Victor Stinnercb043522010-09-10 23:49:04 +000010083 errno = 0;
10084 len = confstr(name, buffer, sizeof(buffer));
10085 if (len == 0) {
10086 if (errno) {
10087 posix_error();
10088 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010089 }
10090 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010091 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010092 }
10093 }
Victor Stinnercb043522010-09-10 23:49:04 +000010094
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010095 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010096 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010097 char *buf = PyMem_Malloc(len);
10098 if (buf == NULL)
10099 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010100 len2 = confstr(name, buf, len);
10101 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010102 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010103 PyMem_Free(buf);
10104 }
10105 else
10106 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010107 return result;
10108}
Larry Hastings2f936352014-08-05 14:04:04 +100010109#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010110
10111
10112#ifdef HAVE_SYSCONF
10113static struct constdef posix_constants_sysconf[] = {
10114#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
Fred Draked86ed291999-12-15 15:34:33 +000010144#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010146#endif
10147#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010149#endif
Fred Drakec9680921999-12-13 16:37:25 +000010150#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
Fred Drakec9680921999-12-13 16:37:25 +000010153#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
Fred Draked86ed291999-12-15 15:34:33 +000010168#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010170#endif
Fred Drakec9680921999-12-13 16:37:25 +000010171#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
Fred Draked86ed291999-12-15 15:34:33 +000010186#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010188#endif
Fred Drakec9680921999-12-13 16:37:25 +000010189#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
Fred Draked86ed291999-12-15 15:34:33 +000010258#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010260#endif
Fred Drakec9680921999-12-13 16:37:25 +000010261#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
Fred Draked86ed291999-12-15 15:34:33 +000010270#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010272#endif
Fred Drakec9680921999-12-13 16:37:25 +000010273#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
Fred Draked86ed291999-12-15 15:34:33 +000010276#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010278#endif
10279#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010281#endif
Fred Drakec9680921999-12-13 16:37:25 +000010282#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
Fred Draked86ed291999-12-15 15:34:33 +000010294#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010296#endif
Fred Drakec9680921999-12-13 16:37:25 +000010297#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
Fred Draked86ed291999-12-15 15:34:33 +000010318#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010320#endif
Fred Drakec9680921999-12-13 16:37:25 +000010321#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
Fred Draked86ed291999-12-15 15:34:33 +000010327#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010329#endif
Fred Drakec9680921999-12-13 16:37:25 +000010330#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
Fred Draked86ed291999-12-15 15:34:33 +000010357#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010359#endif
10360#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010362#endif
Fred Drakec9680921999-12-13 16:37:25 +000010363#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010407#endif
10408#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
10411#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010413#endif
10414#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010416#endif
10417#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010419#endif
10420#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010422#endif
10423#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010425#endif
10426#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010428#endif
10429#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010431#endif
10432#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010434#endif
10435#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010437#endif
10438#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010440#endif
10441#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010443#endif
10444#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010446#endif
10447#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010449#endif
10450#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010452#endif
10453#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010455#endif
10456#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010458#endif
10459#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010461#endif
10462#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010464#endif
10465#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010467#endif
Fred Draked86ed291999-12-15 15:34:33 +000010468#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010470#endif
Fred Drakec9680921999-12-13 16:37:25 +000010471#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010473#endif
10474#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010476#endif
10477#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010479#endif
10480#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010482#endif
10483#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010485#endif
10486#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
10501#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010503#endif
10504#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
10507#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010509#endif
10510#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010512#endif
10513#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010515#endif
10516#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
10564#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
10567#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010569#endif
10570#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010572#endif
10573#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010575#endif
10576#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010578#endif
10579#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010581#endif
10582#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010584#endif
10585#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010587#endif
10588#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010590#endif
10591#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010593#endif
10594#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010596#endif
10597#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010599#endif
10600#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010602#endif
10603#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010605#endif
10606};
10607
10608static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010609conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010610{
10611 return conv_confname(arg, valuep, posix_constants_sysconf,
10612 sizeof(posix_constants_sysconf)
10613 / sizeof(struct constdef));
10614}
10615
Larry Hastings2f936352014-08-05 14:04:04 +100010616
10617/*[clinic input]
10618os.sysconf -> long
10619 name: sysconf_confname
10620 /
10621
10622Return an integer-valued system configuration variable.
10623[clinic start generated code]*/
10624
Larry Hastings2f936352014-08-05 14:04:04 +100010625static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010626os_sysconf_impl(PyObject *module, int name)
10627/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010628{
10629 long value;
10630
10631 errno = 0;
10632 value = sysconf(name);
10633 if (value == -1 && errno != 0)
10634 posix_error();
10635 return value;
10636}
10637#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010638
10639
Fred Drakebec628d1999-12-15 18:31:10 +000010640/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010641 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010642 * the exported dictionaries that are used to publish information about the
10643 * names available on the host platform.
10644 *
10645 * Sorting the table at runtime ensures that the table is properly ordered
10646 * when used, even for platforms we're not able to test on. It also makes
10647 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010648 */
Fred Drakebec628d1999-12-15 18:31:10 +000010649
10650static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010651cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010652{
10653 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010655 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010657
10658 return strcmp(c1->name, c2->name);
10659}
10660
10661static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010662setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010663 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010664{
Fred Drakebec628d1999-12-15 18:31:10 +000010665 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010666 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010667
10668 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10669 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010670 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010671 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010672
Barry Warsaw3155db32000-04-13 15:20:40 +000010673 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010674 PyObject *o = PyLong_FromLong(table[i].value);
10675 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10676 Py_XDECREF(o);
10677 Py_DECREF(d);
10678 return -1;
10679 }
10680 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010681 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010682 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010683}
10684
Fred Drakebec628d1999-12-15 18:31:10 +000010685/* Return -1 on failure, 0 on success. */
10686static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010687setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010688{
10689#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010690 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010691 sizeof(posix_constants_pathconf)
10692 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010693 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010694 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010695#endif
10696#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010697 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010698 sizeof(posix_constants_confstr)
10699 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010700 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010701 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010702#endif
10703#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010704 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010705 sizeof(posix_constants_sysconf)
10706 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010707 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010708 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010709#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010710 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010711}
Fred Draked86ed291999-12-15 15:34:33 +000010712
10713
Larry Hastings2f936352014-08-05 14:04:04 +100010714/*[clinic input]
10715os.abort
10716
10717Abort the interpreter immediately.
10718
10719This function 'dumps core' or otherwise fails in the hardest way possible
10720on the hosting operating system. This function never returns.
10721[clinic start generated code]*/
10722
Larry Hastings2f936352014-08-05 14:04:04 +100010723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010724os_abort_impl(PyObject *module)
10725/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010726{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010727 abort();
10728 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010729#ifndef __clang__
10730 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10731 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10732 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010733 Py_FatalError("abort() called from Python code didn't abort!");
10734 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010735#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010736}
Fred Drakebec628d1999-12-15 18:31:10 +000010737
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010738#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010739/* Grab ShellExecute dynamically from shell32 */
10740static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010741static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10742 LPCWSTR, INT);
10743static int
10744check_ShellExecute()
10745{
10746 HINSTANCE hShell32;
10747
10748 /* only recheck */
10749 if (-1 == has_ShellExecute) {
10750 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010751 /* Security note: this call is not vulnerable to "DLL hijacking".
10752 SHELL32 is part of "KnownDLLs" and so Windows always load
10753 the system SHELL32.DLL, even if there is another SHELL32.DLL
10754 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010755 hShell32 = LoadLibraryW(L"SHELL32");
10756 Py_END_ALLOW_THREADS
10757 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010758 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10759 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010760 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010761 } else {
10762 has_ShellExecute = 0;
10763 }
10764 }
10765 return has_ShellExecute;
10766}
10767
10768
Steve Dowercc16be82016-09-08 10:35:16 -070010769/*[clinic input]
10770os.startfile
10771 filepath: path_t
10772 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010773
Steve Dowercc16be82016-09-08 10:35:16 -070010774startfile(filepath [, operation])
10775
10776Start a file with its associated application.
10777
10778When "operation" is not specified or "open", this acts like
10779double-clicking the file in Explorer, or giving the file name as an
10780argument to the DOS "start" command: the file is opened with whatever
10781application (if any) its extension is associated.
10782When another "operation" is given, it specifies what should be done with
10783the file. A typical operation is "print".
10784
10785startfile returns as soon as the associated application is launched.
10786There is no option to wait for the application to close, and no way
10787to retrieve the application's exit status.
10788
10789The filepath is relative to the current directory. If you want to use
10790an absolute path, make sure the first character is not a slash ("/");
10791the underlying Win32 ShellExecute function doesn't work if it is.
10792[clinic start generated code]*/
10793
10794static PyObject *
Serhiy Storchaka45a7b762018-12-14 11:56:48 +020010795os_startfile_impl(PyObject *module, path_t *filepath,
10796 const Py_UNICODE *operation)
10797/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070010798{
10799 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010800
10801 if(!check_ShellExecute()) {
10802 /* If the OS doesn't have ShellExecute, return a
10803 NotImplementedError. */
10804 return PyErr_Format(PyExc_NotImplementedError,
10805 "startfile not available on this platform");
10806 }
10807
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010809 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010810 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 Py_END_ALLOW_THREADS
10812
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010814 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010815 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 }
Steve Dowercc16be82016-09-08 10:35:16 -070010817 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010818}
Larry Hastings2f936352014-08-05 14:04:04 +100010819#endif /* MS_WINDOWS */
10820
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010821
Martin v. Löwis438b5342002-12-27 10:16:42 +000010822#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010823/*[clinic input]
10824os.getloadavg
10825
10826Return average recent system load information.
10827
10828Return the number of processes in the system run queue averaged over
10829the last 1, 5, and 15 minutes as a tuple of three floats.
10830Raises OSError if the load average was unobtainable.
10831[clinic start generated code]*/
10832
Larry Hastings2f936352014-08-05 14:04:04 +100010833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010834os_getloadavg_impl(PyObject *module)
10835/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010836{
10837 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010838 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010839 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10840 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010841 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010842 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010843}
Larry Hastings2f936352014-08-05 14:04:04 +100010844#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010845
Larry Hastings2f936352014-08-05 14:04:04 +100010846
10847/*[clinic input]
10848os.device_encoding
10849 fd: int
10850
10851Return a string describing the encoding of a terminal's file descriptor.
10852
10853The file descriptor must be attached to a terminal.
10854If the device is not a terminal, return None.
10855[clinic start generated code]*/
10856
Larry Hastings2f936352014-08-05 14:04:04 +100010857static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010858os_device_encoding_impl(PyObject *module, int fd)
10859/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010860{
Brett Cannonefb00c02012-02-29 18:31:31 -050010861 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010862}
10863
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010864
Larry Hastings2f936352014-08-05 14:04:04 +100010865#ifdef HAVE_SETRESUID
10866/*[clinic input]
10867os.setresuid
10868
10869 ruid: uid_t
10870 euid: uid_t
10871 suid: uid_t
10872 /
10873
10874Set the current process's real, effective, and saved user ids.
10875[clinic start generated code]*/
10876
Larry Hastings2f936352014-08-05 14:04:04 +100010877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010878os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10879/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010880{
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 if (setresuid(ruid, euid, suid) < 0)
10882 return posix_error();
10883 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010884}
Larry Hastings2f936352014-08-05 14:04:04 +100010885#endif /* HAVE_SETRESUID */
10886
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010887
10888#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010889/*[clinic input]
10890os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010891
Larry Hastings2f936352014-08-05 14:04:04 +100010892 rgid: gid_t
10893 egid: gid_t
10894 sgid: gid_t
10895 /
10896
10897Set the current process's real, effective, and saved group ids.
10898[clinic start generated code]*/
10899
Larry Hastings2f936352014-08-05 14:04:04 +100010900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010901os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10902/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010903{
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 if (setresgid(rgid, egid, sgid) < 0)
10905 return posix_error();
10906 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010907}
Larry Hastings2f936352014-08-05 14:04:04 +100010908#endif /* HAVE_SETRESGID */
10909
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010910
10911#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010912/*[clinic input]
10913os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010914
Larry Hastings2f936352014-08-05 14:04:04 +100010915Return a tuple of the current process's real, effective, and saved user ids.
10916[clinic start generated code]*/
10917
Larry Hastings2f936352014-08-05 14:04:04 +100010918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010919os_getresuid_impl(PyObject *module)
10920/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010921{
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 if (getresuid(&ruid, &euid, &suid) < 0)
10924 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010925 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10926 _PyLong_FromUid(euid),
10927 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010928}
Larry Hastings2f936352014-08-05 14:04:04 +100010929#endif /* HAVE_GETRESUID */
10930
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010931
10932#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010933/*[clinic input]
10934os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010935
Larry Hastings2f936352014-08-05 14:04:04 +100010936Return a tuple of the current process's real, effective, and saved group ids.
10937[clinic start generated code]*/
10938
Larry Hastings2f936352014-08-05 14:04:04 +100010939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010940os_getresgid_impl(PyObject *module)
10941/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010942{
10943 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 if (getresgid(&rgid, &egid, &sgid) < 0)
10945 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010946 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10947 _PyLong_FromGid(egid),
10948 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010949}
Larry Hastings2f936352014-08-05 14:04:04 +100010950#endif /* HAVE_GETRESGID */
10951
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010952
Benjamin Peterson9428d532011-09-14 11:45:52 -040010953#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010954/*[clinic input]
10955os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010956
Larry Hastings2f936352014-08-05 14:04:04 +100010957 path: path_t(allow_fd=True)
10958 attribute: path_t
10959 *
10960 follow_symlinks: bool = True
10961
10962Return the value of extended attribute attribute on path.
10963
BNMetrics08026b12018-11-02 17:56:25 +000010964path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100010965If follow_symlinks is False, and the last element of the path is a symbolic
10966 link, getxattr will examine the symbolic link itself instead of the file
10967 the link points to.
10968
10969[clinic start generated code]*/
10970
Larry Hastings2f936352014-08-05 14:04:04 +100010971static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010972os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010973 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000010974/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010975{
10976 Py_ssize_t i;
10977 PyObject *buffer = NULL;
10978
10979 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10980 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010981
Larry Hastings9cf065c2012-06-22 16:30:09 -070010982 for (i = 0; ; i++) {
10983 void *ptr;
10984 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010985 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010986 Py_ssize_t buffer_size = buffer_sizes[i];
10987 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010988 path_error(path);
10989 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 }
10991 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10992 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010993 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010994 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010995
Larry Hastings9cf065c2012-06-22 16:30:09 -070010996 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010997 if (path->fd >= 0)
10998 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010999 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011000 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011001 else
Larry Hastings2f936352014-08-05 14:04:04 +100011002 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011003 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011004
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 if (result < 0) {
11006 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 if (errno == ERANGE)
11008 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011009 path_error(path);
11010 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 if (result != buffer_size) {
11014 /* Can only shrink. */
11015 _PyBytes_Resize(&buffer, result);
11016 }
11017 break;
11018 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011019
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011021}
11022
Larry Hastings2f936352014-08-05 14:04:04 +100011023
11024/*[clinic input]
11025os.setxattr
11026
11027 path: path_t(allow_fd=True)
11028 attribute: path_t
11029 value: Py_buffer
11030 flags: int = 0
11031 *
11032 follow_symlinks: bool = True
11033
11034Set extended attribute attribute on path to value.
11035
BNMetrics08026b12018-11-02 17:56:25 +000011036path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011037If follow_symlinks is False, and the last element of the path is a symbolic
11038 link, setxattr will modify the symbolic link itself instead of the file
11039 the link points to.
11040
11041[clinic start generated code]*/
11042
Benjamin Peterson799bd802011-08-31 22:15:17 -040011043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011044os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011045 Py_buffer *value, int flags, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011046/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011047{
Larry Hastings2f936352014-08-05 14:04:04 +100011048 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011049
Larry Hastings2f936352014-08-05 14:04:04 +100011050 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011051 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011052
Benjamin Peterson799bd802011-08-31 22:15:17 -040011053 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011054 if (path->fd > -1)
11055 result = fsetxattr(path->fd, attribute->narrow,
11056 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011057 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011058 result = setxattr(path->narrow, attribute->narrow,
11059 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011060 else
Larry Hastings2f936352014-08-05 14:04:04 +100011061 result = lsetxattr(path->narrow, attribute->narrow,
11062 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011063 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011064
Larry Hastings9cf065c2012-06-22 16:30:09 -070011065 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011066 path_error(path);
11067 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011068 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011069
Larry Hastings2f936352014-08-05 14:04:04 +100011070 Py_RETURN_NONE;
11071}
11072
11073
11074/*[clinic input]
11075os.removexattr
11076
11077 path: path_t(allow_fd=True)
11078 attribute: path_t
11079 *
11080 follow_symlinks: bool = True
11081
11082Remove extended attribute attribute on path.
11083
BNMetrics08026b12018-11-02 17:56:25 +000011084path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011085If follow_symlinks is False, and the last element of the path is a symbolic
11086 link, removexattr will modify the symbolic link itself instead of the file
11087 the link points to.
11088
11089[clinic start generated code]*/
11090
Larry Hastings2f936352014-08-05 14:04:04 +100011091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011092os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011093 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011094/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011095{
11096 ssize_t result;
11097
11098 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11099 return NULL;
11100
11101 Py_BEGIN_ALLOW_THREADS;
11102 if (path->fd > -1)
11103 result = fremovexattr(path->fd, attribute->narrow);
11104 else if (follow_symlinks)
11105 result = removexattr(path->narrow, attribute->narrow);
11106 else
11107 result = lremovexattr(path->narrow, attribute->narrow);
11108 Py_END_ALLOW_THREADS;
11109
11110 if (result) {
11111 return path_error(path);
11112 }
11113
11114 Py_RETURN_NONE;
11115}
11116
11117
11118/*[clinic input]
11119os.listxattr
11120
11121 path: path_t(allow_fd=True, nullable=True) = None
11122 *
11123 follow_symlinks: bool = True
11124
11125Return a list of extended attributes on path.
11126
BNMetrics08026b12018-11-02 17:56:25 +000011127path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011128if path is None, listxattr will examine the current directory.
11129If follow_symlinks is False, and the last element of the path is a symbolic
11130 link, listxattr will examine the symbolic link itself instead of the file
11131 the link points to.
11132[clinic start generated code]*/
11133
Larry Hastings2f936352014-08-05 14:04:04 +100011134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011135os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011136/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011137{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011138 Py_ssize_t i;
11139 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011140 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011141 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011142
Larry Hastings2f936352014-08-05 14:04:04 +100011143 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011144 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011145
Larry Hastings2f936352014-08-05 14:04:04 +100011146 name = path->narrow ? path->narrow : ".";
11147
Larry Hastings9cf065c2012-06-22 16:30:09 -070011148 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011149 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011150 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011151 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011152 Py_ssize_t buffer_size = buffer_sizes[i];
11153 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011154 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011155 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011156 break;
11157 }
11158 buffer = PyMem_MALLOC(buffer_size);
11159 if (!buffer) {
11160 PyErr_NoMemory();
11161 break;
11162 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011163
Larry Hastings9cf065c2012-06-22 16:30:09 -070011164 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011165 if (path->fd > -1)
11166 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011167 else if (follow_symlinks)
11168 length = listxattr(name, buffer, buffer_size);
11169 else
11170 length = llistxattr(name, buffer, buffer_size);
11171 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011172
Larry Hastings9cf065c2012-06-22 16:30:09 -070011173 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011174 if (errno == ERANGE) {
11175 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011176 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011177 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011178 }
Larry Hastings2f936352014-08-05 14:04:04 +100011179 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011180 break;
11181 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011182
Larry Hastings9cf065c2012-06-22 16:30:09 -070011183 result = PyList_New(0);
11184 if (!result) {
11185 goto exit;
11186 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011187
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188 end = buffer + length;
11189 for (trace = start = buffer; trace != end; trace++) {
11190 if (!*trace) {
11191 int error;
11192 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11193 trace - start);
11194 if (!attribute) {
11195 Py_DECREF(result);
11196 result = NULL;
11197 goto exit;
11198 }
11199 error = PyList_Append(result, attribute);
11200 Py_DECREF(attribute);
11201 if (error) {
11202 Py_DECREF(result);
11203 result = NULL;
11204 goto exit;
11205 }
11206 start = trace + 1;
11207 }
11208 }
11209 break;
11210 }
11211exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011212 if (buffer)
11213 PyMem_FREE(buffer);
11214 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011215}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011216#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011217
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011218
Larry Hastings2f936352014-08-05 14:04:04 +100011219/*[clinic input]
11220os.urandom
11221
11222 size: Py_ssize_t
11223 /
11224
11225Return a bytes object containing random bytes suitable for cryptographic use.
11226[clinic start generated code]*/
11227
Larry Hastings2f936352014-08-05 14:04:04 +100011228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011229os_urandom_impl(PyObject *module, Py_ssize_t size)
11230/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011231{
11232 PyObject *bytes;
11233 int result;
11234
Georg Brandl2fb477c2012-02-21 00:33:36 +010011235 if (size < 0)
11236 return PyErr_Format(PyExc_ValueError,
11237 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011238 bytes = PyBytes_FromStringAndSize(NULL, size);
11239 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011240 return NULL;
11241
Victor Stinnere66987e2016-09-06 16:33:52 -070011242 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011243 if (result == -1) {
11244 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011245 return NULL;
11246 }
Larry Hastings2f936352014-08-05 14:04:04 +100011247 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011248}
11249
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011250/* Terminal size querying */
11251
11252static PyTypeObject TerminalSizeType;
11253
11254PyDoc_STRVAR(TerminalSize_docstring,
11255 "A tuple of (columns, lines) for holding terminal window size");
11256
11257static PyStructSequence_Field TerminalSize_fields[] = {
11258 {"columns", "width of the terminal window in characters"},
11259 {"lines", "height of the terminal window in characters"},
11260 {NULL, NULL}
11261};
11262
11263static PyStructSequence_Desc TerminalSize_desc = {
11264 "os.terminal_size",
11265 TerminalSize_docstring,
11266 TerminalSize_fields,
11267 2,
11268};
11269
11270#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011271/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011272PyDoc_STRVAR(termsize__doc__,
11273 "Return the size of the terminal window as (columns, lines).\n" \
11274 "\n" \
11275 "The optional argument fd (default standard output) specifies\n" \
11276 "which file descriptor should be queried.\n" \
11277 "\n" \
11278 "If the file descriptor is not connected to a terminal, an OSError\n" \
11279 "is thrown.\n" \
11280 "\n" \
11281 "This function will only be defined if an implementation is\n" \
11282 "available for this system.\n" \
11283 "\n" \
11284 "shutil.get_terminal_size is the high-level function which should \n" \
11285 "normally be used, os.get_terminal_size is the low-level implementation.");
11286
11287static PyObject*
11288get_terminal_size(PyObject *self, PyObject *args)
11289{
11290 int columns, lines;
11291 PyObject *termsize;
11292
11293 int fd = fileno(stdout);
11294 /* Under some conditions stdout may not be connected and
11295 * fileno(stdout) may point to an invalid file descriptor. For example
11296 * GUI apps don't have valid standard streams by default.
11297 *
11298 * If this happens, and the optional fd argument is not present,
11299 * the ioctl below will fail returning EBADF. This is what we want.
11300 */
11301
11302 if (!PyArg_ParseTuple(args, "|i", &fd))
11303 return NULL;
11304
11305#ifdef TERMSIZE_USE_IOCTL
11306 {
11307 struct winsize w;
11308 if (ioctl(fd, TIOCGWINSZ, &w))
11309 return PyErr_SetFromErrno(PyExc_OSError);
11310 columns = w.ws_col;
11311 lines = w.ws_row;
11312 }
11313#endif /* TERMSIZE_USE_IOCTL */
11314
11315#ifdef TERMSIZE_USE_CONIO
11316 {
11317 DWORD nhandle;
11318 HANDLE handle;
11319 CONSOLE_SCREEN_BUFFER_INFO csbi;
11320 switch (fd) {
11321 case 0: nhandle = STD_INPUT_HANDLE;
11322 break;
11323 case 1: nhandle = STD_OUTPUT_HANDLE;
11324 break;
11325 case 2: nhandle = STD_ERROR_HANDLE;
11326 break;
11327 default:
11328 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11329 }
11330 handle = GetStdHandle(nhandle);
11331 if (handle == NULL)
11332 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11333 if (handle == INVALID_HANDLE_VALUE)
11334 return PyErr_SetFromWindowsErr(0);
11335
11336 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11337 return PyErr_SetFromWindowsErr(0);
11338
11339 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11340 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11341 }
11342#endif /* TERMSIZE_USE_CONIO */
11343
11344 termsize = PyStructSequence_New(&TerminalSizeType);
11345 if (termsize == NULL)
11346 return NULL;
11347 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11348 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11349 if (PyErr_Occurred()) {
11350 Py_DECREF(termsize);
11351 return NULL;
11352 }
11353 return termsize;
11354}
11355#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11356
Larry Hastings2f936352014-08-05 14:04:04 +100011357
11358/*[clinic input]
11359os.cpu_count
11360
Charles-François Natali80d62e62015-08-13 20:37:08 +010011361Return the number of CPUs in the system; return None if indeterminable.
11362
11363This number is not equivalent to the number of CPUs the current process can
11364use. The number of usable CPUs can be obtained with
11365``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011366[clinic start generated code]*/
11367
Larry Hastings2f936352014-08-05 14:04:04 +100011368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011369os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011370/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011371{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011372 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011373#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011374 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11375 Need to fallback to Vista behavior if this call isn't present */
11376 HINSTANCE hKernel32;
11377 hKernel32 = GetModuleHandleW(L"KERNEL32");
11378
11379 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11380 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11381 "GetMaximumProcessorCount");
11382 if (_GetMaximumProcessorCount != NULL) {
11383 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11384 }
11385 else {
11386 SYSTEM_INFO sysinfo;
11387 GetSystemInfo(&sysinfo);
11388 ncpu = sysinfo.dwNumberOfProcessors;
11389 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011390#elif defined(__hpux)
11391 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11392#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11393 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011394#elif defined(__DragonFly__) || \
11395 defined(__OpenBSD__) || \
11396 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011397 defined(__NetBSD__) || \
11398 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011399 int mib[2];
11400 size_t len = sizeof(ncpu);
11401 mib[0] = CTL_HW;
11402 mib[1] = HW_NCPU;
11403 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11404 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011405#endif
11406 if (ncpu >= 1)
11407 return PyLong_FromLong(ncpu);
11408 else
11409 Py_RETURN_NONE;
11410}
11411
Victor Stinnerdaf45552013-08-28 00:53:59 +020011412
Larry Hastings2f936352014-08-05 14:04:04 +100011413/*[clinic input]
11414os.get_inheritable -> bool
11415
11416 fd: int
11417 /
11418
11419Get the close-on-exe flag of the specified file descriptor.
11420[clinic start generated code]*/
11421
Larry Hastings2f936352014-08-05 14:04:04 +100011422static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011423os_get_inheritable_impl(PyObject *module, int fd)
11424/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011425{
Steve Dower8fc89802015-04-12 00:26:27 -040011426 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011427 _Py_BEGIN_SUPPRESS_IPH
11428 return_value = _Py_get_inheritable(fd);
11429 _Py_END_SUPPRESS_IPH
11430 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011431}
11432
11433
11434/*[clinic input]
11435os.set_inheritable
11436 fd: int
11437 inheritable: int
11438 /
11439
11440Set the inheritable flag of the specified file descriptor.
11441[clinic start generated code]*/
11442
Larry Hastings2f936352014-08-05 14:04:04 +100011443static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011444os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11445/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011446{
Steve Dower8fc89802015-04-12 00:26:27 -040011447 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011448
Steve Dower8fc89802015-04-12 00:26:27 -040011449 _Py_BEGIN_SUPPRESS_IPH
11450 result = _Py_set_inheritable(fd, inheritable, NULL);
11451 _Py_END_SUPPRESS_IPH
11452 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011453 return NULL;
11454 Py_RETURN_NONE;
11455}
11456
11457
11458#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011459/*[clinic input]
11460os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011461 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011462 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011463
Larry Hastings2f936352014-08-05 14:04:04 +100011464Get the close-on-exe flag of the specified file descriptor.
11465[clinic start generated code]*/
11466
Larry Hastings2f936352014-08-05 14:04:04 +100011467static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011468os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011469/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011470{
11471 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011472
11473 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11474 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011475 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011476 }
11477
Larry Hastings2f936352014-08-05 14:04:04 +100011478 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011479}
11480
Victor Stinnerdaf45552013-08-28 00:53:59 +020011481
Larry Hastings2f936352014-08-05 14:04:04 +100011482/*[clinic input]
11483os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011484 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011485 inheritable: bool
11486 /
11487
11488Set the inheritable flag of the specified handle.
11489[clinic start generated code]*/
11490
Larry Hastings2f936352014-08-05 14:04:04 +100011491static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011492os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011493 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011494/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011495{
11496 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011497 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11498 PyErr_SetFromWindowsErr(0);
11499 return NULL;
11500 }
11501 Py_RETURN_NONE;
11502}
Larry Hastings2f936352014-08-05 14:04:04 +100011503#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011504
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011505#ifndef MS_WINDOWS
11506PyDoc_STRVAR(get_blocking__doc__,
11507 "get_blocking(fd) -> bool\n" \
11508 "\n" \
11509 "Get the blocking mode of the file descriptor:\n" \
11510 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11511
11512static PyObject*
11513posix_get_blocking(PyObject *self, PyObject *args)
11514{
11515 int fd;
11516 int blocking;
11517
11518 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11519 return NULL;
11520
Steve Dower8fc89802015-04-12 00:26:27 -040011521 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011522 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011523 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011524 if (blocking < 0)
11525 return NULL;
11526 return PyBool_FromLong(blocking);
11527}
11528
11529PyDoc_STRVAR(set_blocking__doc__,
11530 "set_blocking(fd, blocking)\n" \
11531 "\n" \
11532 "Set the blocking mode of the specified file descriptor.\n" \
11533 "Set the O_NONBLOCK flag if blocking is False,\n" \
11534 "clear the O_NONBLOCK flag otherwise.");
11535
11536static PyObject*
11537posix_set_blocking(PyObject *self, PyObject *args)
11538{
Steve Dower8fc89802015-04-12 00:26:27 -040011539 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011540
11541 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11542 return NULL;
11543
Steve Dower8fc89802015-04-12 00:26:27 -040011544 _Py_BEGIN_SUPPRESS_IPH
11545 result = _Py_set_blocking(fd, blocking);
11546 _Py_END_SUPPRESS_IPH
11547 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011548 return NULL;
11549 Py_RETURN_NONE;
11550}
11551#endif /* !MS_WINDOWS */
11552
11553
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011554/*[clinic input]
11555class os.DirEntry "DirEntry *" "&DirEntryType"
11556[clinic start generated code]*/
11557/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011558
11559typedef struct {
11560 PyObject_HEAD
11561 PyObject *name;
11562 PyObject *path;
11563 PyObject *stat;
11564 PyObject *lstat;
11565#ifdef MS_WINDOWS
11566 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011567 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011568 int got_file_index;
11569#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011570#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011571 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011572#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011573 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011574 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011575#endif
11576} DirEntry;
11577
11578static void
11579DirEntry_dealloc(DirEntry *entry)
11580{
11581 Py_XDECREF(entry->name);
11582 Py_XDECREF(entry->path);
11583 Py_XDECREF(entry->stat);
11584 Py_XDECREF(entry->lstat);
11585 Py_TYPE(entry)->tp_free((PyObject *)entry);
11586}
11587
11588/* Forward reference */
11589static int
11590DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11591
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011592/*[clinic input]
11593os.DirEntry.is_symlink -> bool
11594
11595Return True if the entry is a symbolic link; cached per entry.
11596[clinic start generated code]*/
11597
Victor Stinner6036e442015-03-08 01:58:04 +010011598static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011599os_DirEntry_is_symlink_impl(DirEntry *self)
11600/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011601{
11602#ifdef MS_WINDOWS
11603 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011604#elif defined(HAVE_DIRENT_D_TYPE)
11605 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011606 if (self->d_type != DT_UNKNOWN)
11607 return self->d_type == DT_LNK;
11608 else
11609 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011610#else
11611 /* POSIX without d_type */
11612 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011613#endif
11614}
11615
11616static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011617DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11618{
11619 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011620 STRUCT_STAT st;
11621 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011622
11623#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011624 if (!PyUnicode_FSDecoder(self->path, &ub))
11625 return NULL;
11626 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011627#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011628 if (!PyUnicode_FSConverter(self->path, &ub))
11629 return NULL;
11630 const char *path = PyBytes_AS_STRING(ub);
11631 if (self->dir_fd != DEFAULT_DIR_FD) {
11632#ifdef HAVE_FSTATAT
11633 result = fstatat(self->dir_fd, path, &st,
11634 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11635#else
11636 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11637 return NULL;
11638#endif /* HAVE_FSTATAT */
11639 }
11640 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011641#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011642 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011643 if (follow_symlinks)
11644 result = STAT(path, &st);
11645 else
11646 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011647 }
11648 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011649
11650 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011651 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011652
11653 return _pystat_fromstructstat(&st);
11654}
11655
11656static PyObject *
11657DirEntry_get_lstat(DirEntry *self)
11658{
11659 if (!self->lstat) {
11660#ifdef MS_WINDOWS
11661 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11662#else /* POSIX */
11663 self->lstat = DirEntry_fetch_stat(self, 0);
11664#endif
11665 }
11666 Py_XINCREF(self->lstat);
11667 return self->lstat;
11668}
11669
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011670/*[clinic input]
11671os.DirEntry.stat
11672 *
11673 follow_symlinks: bool = True
11674
11675Return stat_result object for the entry; cached per entry.
11676[clinic start generated code]*/
11677
Victor Stinner6036e442015-03-08 01:58:04 +010011678static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011679os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11680/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011681{
11682 if (!follow_symlinks)
11683 return DirEntry_get_lstat(self);
11684
11685 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011686 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011687 if (result == -1)
11688 return NULL;
11689 else if (result)
11690 self->stat = DirEntry_fetch_stat(self, 1);
11691 else
11692 self->stat = DirEntry_get_lstat(self);
11693 }
11694
11695 Py_XINCREF(self->stat);
11696 return self->stat;
11697}
11698
Victor Stinner6036e442015-03-08 01:58:04 +010011699/* Set exception and return -1 on error, 0 for False, 1 for True */
11700static int
11701DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11702{
11703 PyObject *stat = NULL;
11704 PyObject *st_mode = NULL;
11705 long mode;
11706 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011707#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011708 int is_symlink;
11709 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011710#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011711#ifdef MS_WINDOWS
11712 unsigned long dir_bits;
11713#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011714 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011715
11716#ifdef MS_WINDOWS
11717 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11718 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011719#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011720 is_symlink = self->d_type == DT_LNK;
11721 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11722#endif
11723
Victor Stinner35a97c02015-03-08 02:59:09 +010011724#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011725 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011726#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011727 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011728 if (!stat) {
11729 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11730 /* If file doesn't exist (anymore), then return False
11731 (i.e., say it's not a file/directory) */
11732 PyErr_Clear();
11733 return 0;
11734 }
11735 goto error;
11736 }
11737 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11738 if (!st_mode)
11739 goto error;
11740
11741 mode = PyLong_AsLong(st_mode);
11742 if (mode == -1 && PyErr_Occurred())
11743 goto error;
11744 Py_CLEAR(st_mode);
11745 Py_CLEAR(stat);
11746 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011747#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011748 }
11749 else if (is_symlink) {
11750 assert(mode_bits != S_IFLNK);
11751 result = 0;
11752 }
11753 else {
11754 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11755#ifdef MS_WINDOWS
11756 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11757 if (mode_bits == S_IFDIR)
11758 result = dir_bits != 0;
11759 else
11760 result = dir_bits == 0;
11761#else /* POSIX */
11762 if (mode_bits == S_IFDIR)
11763 result = self->d_type == DT_DIR;
11764 else
11765 result = self->d_type == DT_REG;
11766#endif
11767 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011768#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011769
11770 return result;
11771
11772error:
11773 Py_XDECREF(st_mode);
11774 Py_XDECREF(stat);
11775 return -1;
11776}
11777
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011778/*[clinic input]
11779os.DirEntry.is_dir -> bool
11780 *
11781 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011782
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011783Return True if the entry is a directory; cached per entry.
11784[clinic start generated code]*/
11785
11786static int
11787os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11788/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11789{
11790 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011791}
11792
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011793/*[clinic input]
11794os.DirEntry.is_file -> bool
11795 *
11796 follow_symlinks: bool = True
11797
11798Return True if the entry is a file; cached per entry.
11799[clinic start generated code]*/
11800
11801static int
11802os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11803/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011804{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011805 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011806}
11807
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011808/*[clinic input]
11809os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011810
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011811Return inode of the entry; cached per entry.
11812[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011813
11814static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011815os_DirEntry_inode_impl(DirEntry *self)
11816/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011817{
11818#ifdef MS_WINDOWS
11819 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011820 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011821 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011822 STRUCT_STAT stat;
11823 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011824
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011825 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011826 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011827 path = PyUnicode_AsUnicode(unicode);
11828 result = LSTAT(path, &stat);
11829 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011830
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011831 if (result != 0)
11832 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011833
11834 self->win32_file_index = stat.st_ino;
11835 self->got_file_index = 1;
11836 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011837 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11838 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011839#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011840 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11841 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011842#endif
11843}
11844
11845static PyObject *
11846DirEntry_repr(DirEntry *self)
11847{
11848 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11849}
11850
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011851/*[clinic input]
11852os.DirEntry.__fspath__
11853
11854Returns the path for the entry.
11855[clinic start generated code]*/
11856
Brett Cannon96881cd2016-06-10 14:37:21 -070011857static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011858os_DirEntry___fspath___impl(DirEntry *self)
11859/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011860{
11861 Py_INCREF(self->path);
11862 return self->path;
11863}
11864
Victor Stinner6036e442015-03-08 01:58:04 +010011865static PyMemberDef DirEntry_members[] = {
11866 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11867 "the entry's base filename, relative to scandir() \"path\" argument"},
11868 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11869 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11870 {NULL}
11871};
11872
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011873#include "clinic/posixmodule.c.h"
11874
Victor Stinner6036e442015-03-08 01:58:04 +010011875static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011876 OS_DIRENTRY_IS_DIR_METHODDEF
11877 OS_DIRENTRY_IS_FILE_METHODDEF
11878 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11879 OS_DIRENTRY_STAT_METHODDEF
11880 OS_DIRENTRY_INODE_METHODDEF
11881 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011882 {NULL}
11883};
11884
Benjamin Peterson5646de42015-04-12 17:56:34 -040011885static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011886 PyVarObject_HEAD_INIT(NULL, 0)
11887 MODNAME ".DirEntry", /* tp_name */
11888 sizeof(DirEntry), /* tp_basicsize */
11889 0, /* tp_itemsize */
11890 /* methods */
11891 (destructor)DirEntry_dealloc, /* tp_dealloc */
11892 0, /* tp_print */
11893 0, /* tp_getattr */
11894 0, /* tp_setattr */
11895 0, /* tp_compare */
11896 (reprfunc)DirEntry_repr, /* tp_repr */
11897 0, /* tp_as_number */
11898 0, /* tp_as_sequence */
11899 0, /* tp_as_mapping */
11900 0, /* tp_hash */
11901 0, /* tp_call */
11902 0, /* tp_str */
11903 0, /* tp_getattro */
11904 0, /* tp_setattro */
11905 0, /* tp_as_buffer */
11906 Py_TPFLAGS_DEFAULT, /* tp_flags */
11907 0, /* tp_doc */
11908 0, /* tp_traverse */
11909 0, /* tp_clear */
11910 0, /* tp_richcompare */
11911 0, /* tp_weaklistoffset */
11912 0, /* tp_iter */
11913 0, /* tp_iternext */
11914 DirEntry_methods, /* tp_methods */
11915 DirEntry_members, /* tp_members */
11916};
11917
11918#ifdef MS_WINDOWS
11919
11920static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011921join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011922{
11923 Py_ssize_t path_len;
11924 Py_ssize_t size;
11925 wchar_t *result;
11926 wchar_t ch;
11927
11928 if (!path_wide) { /* Default arg: "." */
11929 path_wide = L".";
11930 path_len = 1;
11931 }
11932 else {
11933 path_len = wcslen(path_wide);
11934 }
11935
11936 /* The +1's are for the path separator and the NUL */
11937 size = path_len + 1 + wcslen(filename) + 1;
11938 result = PyMem_New(wchar_t, size);
11939 if (!result) {
11940 PyErr_NoMemory();
11941 return NULL;
11942 }
11943 wcscpy(result, path_wide);
11944 if (path_len > 0) {
11945 ch = result[path_len - 1];
11946 if (ch != SEP && ch != ALTSEP && ch != L':')
11947 result[path_len++] = SEP;
11948 wcscpy(result + path_len, filename);
11949 }
11950 return result;
11951}
11952
11953static PyObject *
11954DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11955{
11956 DirEntry *entry;
11957 BY_HANDLE_FILE_INFORMATION file_info;
11958 ULONG reparse_tag;
11959 wchar_t *joined_path;
11960
11961 entry = PyObject_New(DirEntry, &DirEntryType);
11962 if (!entry)
11963 return NULL;
11964 entry->name = NULL;
11965 entry->path = NULL;
11966 entry->stat = NULL;
11967 entry->lstat = NULL;
11968 entry->got_file_index = 0;
11969
11970 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11971 if (!entry->name)
11972 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011973 if (path->narrow) {
11974 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11975 if (!entry->name)
11976 goto error;
11977 }
Victor Stinner6036e442015-03-08 01:58:04 +010011978
11979 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11980 if (!joined_path)
11981 goto error;
11982
11983 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11984 PyMem_Free(joined_path);
11985 if (!entry->path)
11986 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011987 if (path->narrow) {
11988 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11989 if (!entry->path)
11990 goto error;
11991 }
Victor Stinner6036e442015-03-08 01:58:04 +010011992
Steve Dowercc16be82016-09-08 10:35:16 -070011993 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011994 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11995
11996 return (PyObject *)entry;
11997
11998error:
11999 Py_DECREF(entry);
12000 return NULL;
12001}
12002
12003#else /* POSIX */
12004
12005static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012006join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012007{
12008 Py_ssize_t path_len;
12009 Py_ssize_t size;
12010 char *result;
12011
12012 if (!path_narrow) { /* Default arg: "." */
12013 path_narrow = ".";
12014 path_len = 1;
12015 }
12016 else {
12017 path_len = strlen(path_narrow);
12018 }
12019
12020 if (filename_len == -1)
12021 filename_len = strlen(filename);
12022
12023 /* The +1's are for the path separator and the NUL */
12024 size = path_len + 1 + filename_len + 1;
12025 result = PyMem_New(char, size);
12026 if (!result) {
12027 PyErr_NoMemory();
12028 return NULL;
12029 }
12030 strcpy(result, path_narrow);
12031 if (path_len > 0 && result[path_len - 1] != '/')
12032 result[path_len++] = '/';
12033 strcpy(result + path_len, filename);
12034 return result;
12035}
12036
12037static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012038DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012039 ino_t d_ino
12040#ifdef HAVE_DIRENT_D_TYPE
12041 , unsigned char d_type
12042#endif
12043 )
Victor Stinner6036e442015-03-08 01:58:04 +010012044{
12045 DirEntry *entry;
12046 char *joined_path;
12047
12048 entry = PyObject_New(DirEntry, &DirEntryType);
12049 if (!entry)
12050 return NULL;
12051 entry->name = NULL;
12052 entry->path = NULL;
12053 entry->stat = NULL;
12054 entry->lstat = NULL;
12055
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012056 if (path->fd != -1) {
12057 entry->dir_fd = path->fd;
12058 joined_path = NULL;
12059 }
12060 else {
12061 entry->dir_fd = DEFAULT_DIR_FD;
12062 joined_path = join_path_filename(path->narrow, name, name_len);
12063 if (!joined_path)
12064 goto error;
12065 }
Victor Stinner6036e442015-03-08 01:58:04 +010012066
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012067 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012068 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012069 if (joined_path)
12070 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012071 }
12072 else {
12073 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012074 if (joined_path)
12075 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012076 }
12077 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012078 if (!entry->name)
12079 goto error;
12080
12081 if (path->fd != -1) {
12082 entry->path = entry->name;
12083 Py_INCREF(entry->path);
12084 }
12085 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012086 goto error;
12087
Victor Stinner35a97c02015-03-08 02:59:09 +010012088#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012089 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012090#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012091 entry->d_ino = d_ino;
12092
12093 return (PyObject *)entry;
12094
12095error:
12096 Py_XDECREF(entry);
12097 return NULL;
12098}
12099
12100#endif
12101
12102
12103typedef struct {
12104 PyObject_HEAD
12105 path_t path;
12106#ifdef MS_WINDOWS
12107 HANDLE handle;
12108 WIN32_FIND_DATAW file_data;
12109 int first_time;
12110#else /* POSIX */
12111 DIR *dirp;
12112#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012113#ifdef HAVE_FDOPENDIR
12114 int fd;
12115#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012116} ScandirIterator;
12117
12118#ifdef MS_WINDOWS
12119
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012120static int
12121ScandirIterator_is_closed(ScandirIterator *iterator)
12122{
12123 return iterator->handle == INVALID_HANDLE_VALUE;
12124}
12125
Victor Stinner6036e442015-03-08 01:58:04 +010012126static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012127ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012128{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012129 HANDLE handle = iterator->handle;
12130
12131 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012132 return;
12133
Victor Stinner6036e442015-03-08 01:58:04 +010012134 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012135 Py_BEGIN_ALLOW_THREADS
12136 FindClose(handle);
12137 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012138}
12139
12140static PyObject *
12141ScandirIterator_iternext(ScandirIterator *iterator)
12142{
12143 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12144 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012145 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012146
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012147 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012148 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012149 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012150
12151 while (1) {
12152 if (!iterator->first_time) {
12153 Py_BEGIN_ALLOW_THREADS
12154 success = FindNextFileW(iterator->handle, file_data);
12155 Py_END_ALLOW_THREADS
12156 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012157 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012158 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012159 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012160 break;
12161 }
12162 }
12163 iterator->first_time = 0;
12164
12165 /* Skip over . and .. */
12166 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012167 wcscmp(file_data->cFileName, L"..") != 0) {
12168 entry = DirEntry_from_find_data(&iterator->path, file_data);
12169 if (!entry)
12170 break;
12171 return entry;
12172 }
Victor Stinner6036e442015-03-08 01:58:04 +010012173
12174 /* Loop till we get a non-dot directory or finish iterating */
12175 }
12176
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012177 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012178 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012179 return NULL;
12180}
12181
12182#else /* POSIX */
12183
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012184static int
12185ScandirIterator_is_closed(ScandirIterator *iterator)
12186{
12187 return !iterator->dirp;
12188}
12189
Victor Stinner6036e442015-03-08 01:58:04 +010012190static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012191ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012192{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012193 DIR *dirp = iterator->dirp;
12194
12195 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012196 return;
12197
Victor Stinner6036e442015-03-08 01:58:04 +010012198 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012199 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012200#ifdef HAVE_FDOPENDIR
12201 if (iterator->path.fd != -1)
12202 rewinddir(dirp);
12203#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012204 closedir(dirp);
12205 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012206 return;
12207}
12208
12209static PyObject *
12210ScandirIterator_iternext(ScandirIterator *iterator)
12211{
12212 struct dirent *direntp;
12213 Py_ssize_t name_len;
12214 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012215 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012216
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012217 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012218 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012219 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012220
12221 while (1) {
12222 errno = 0;
12223 Py_BEGIN_ALLOW_THREADS
12224 direntp = readdir(iterator->dirp);
12225 Py_END_ALLOW_THREADS
12226
12227 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012228 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012229 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012230 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012231 break;
12232 }
12233
12234 /* Skip over . and .. */
12235 name_len = NAMLEN(direntp);
12236 is_dot = direntp->d_name[0] == '.' &&
12237 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12238 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012239 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012240 name_len, direntp->d_ino
12241#ifdef HAVE_DIRENT_D_TYPE
12242 , direntp->d_type
12243#endif
12244 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012245 if (!entry)
12246 break;
12247 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012248 }
12249
12250 /* Loop till we get a non-dot directory or finish iterating */
12251 }
12252
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012253 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012254 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012255 return NULL;
12256}
12257
12258#endif
12259
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012260static PyObject *
12261ScandirIterator_close(ScandirIterator *self, PyObject *args)
12262{
12263 ScandirIterator_closedir(self);
12264 Py_RETURN_NONE;
12265}
12266
12267static PyObject *
12268ScandirIterator_enter(PyObject *self, PyObject *args)
12269{
12270 Py_INCREF(self);
12271 return self;
12272}
12273
12274static PyObject *
12275ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12276{
12277 ScandirIterator_closedir(self);
12278 Py_RETURN_NONE;
12279}
12280
Victor Stinner6036e442015-03-08 01:58:04 +010012281static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012282ScandirIterator_finalize(ScandirIterator *iterator)
12283{
12284 PyObject *error_type, *error_value, *error_traceback;
12285
12286 /* Save the current exception, if any. */
12287 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12288
12289 if (!ScandirIterator_is_closed(iterator)) {
12290 ScandirIterator_closedir(iterator);
12291
12292 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12293 "unclosed scandir iterator %R", iterator)) {
12294 /* Spurious errors can appear at shutdown */
12295 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12296 PyErr_WriteUnraisable((PyObject *) iterator);
12297 }
12298 }
12299 }
12300
Victor Stinner7bfa4092016-03-23 00:43:54 +010012301 path_cleanup(&iterator->path);
12302
12303 /* Restore the saved exception. */
12304 PyErr_Restore(error_type, error_value, error_traceback);
12305}
12306
12307static void
Victor Stinner6036e442015-03-08 01:58:04 +010012308ScandirIterator_dealloc(ScandirIterator *iterator)
12309{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012310 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12311 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012312
Victor Stinner6036e442015-03-08 01:58:04 +010012313 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12314}
12315
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012316static PyMethodDef ScandirIterator_methods[] = {
12317 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12318 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12319 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12320 {NULL}
12321};
12322
Benjamin Peterson5646de42015-04-12 17:56:34 -040012323static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012324 PyVarObject_HEAD_INIT(NULL, 0)
12325 MODNAME ".ScandirIterator", /* tp_name */
12326 sizeof(ScandirIterator), /* tp_basicsize */
12327 0, /* tp_itemsize */
12328 /* methods */
12329 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12330 0, /* tp_print */
12331 0, /* tp_getattr */
12332 0, /* tp_setattr */
12333 0, /* tp_compare */
12334 0, /* tp_repr */
12335 0, /* tp_as_number */
12336 0, /* tp_as_sequence */
12337 0, /* tp_as_mapping */
12338 0, /* tp_hash */
12339 0, /* tp_call */
12340 0, /* tp_str */
12341 0, /* tp_getattro */
12342 0, /* tp_setattro */
12343 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012344 Py_TPFLAGS_DEFAULT
12345 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012346 0, /* tp_doc */
12347 0, /* tp_traverse */
12348 0, /* tp_clear */
12349 0, /* tp_richcompare */
12350 0, /* tp_weaklistoffset */
12351 PyObject_SelfIter, /* tp_iter */
12352 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012353 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012354 0, /* tp_members */
12355 0, /* tp_getset */
12356 0, /* tp_base */
12357 0, /* tp_dict */
12358 0, /* tp_descr_get */
12359 0, /* tp_descr_set */
12360 0, /* tp_dictoffset */
12361 0, /* tp_init */
12362 0, /* tp_alloc */
12363 0, /* tp_new */
12364 0, /* tp_free */
12365 0, /* tp_is_gc */
12366 0, /* tp_bases */
12367 0, /* tp_mro */
12368 0, /* tp_cache */
12369 0, /* tp_subclasses */
12370 0, /* tp_weaklist */
12371 0, /* tp_del */
12372 0, /* tp_version_tag */
12373 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012374};
12375
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012376/*[clinic input]
12377os.scandir
12378
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012379 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012380
12381Return an iterator of DirEntry objects for given path.
12382
BNMetrics08026b12018-11-02 17:56:25 +000012383path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012384is bytes, the names of yielded DirEntry objects will also be bytes; in
12385all other circumstances they will be str.
12386
12387If path is None, uses the path='.'.
12388[clinic start generated code]*/
12389
Victor Stinner6036e442015-03-08 01:58:04 +010012390static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012391os_scandir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +000012392/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012393{
12394 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012395#ifdef MS_WINDOWS
12396 wchar_t *path_strW;
12397#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012398 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012399#ifdef HAVE_FDOPENDIR
12400 int fd = -1;
12401#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012402#endif
12403
12404 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12405 if (!iterator)
12406 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012407
12408#ifdef MS_WINDOWS
12409 iterator->handle = INVALID_HANDLE_VALUE;
12410#else
12411 iterator->dirp = NULL;
12412#endif
12413
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012414 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012415 /* Move the ownership to iterator->path */
12416 path->object = NULL;
12417 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012418
12419#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012420 iterator->first_time = 1;
12421
12422 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12423 if (!path_strW)
12424 goto error;
12425
12426 Py_BEGIN_ALLOW_THREADS
12427 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12428 Py_END_ALLOW_THREADS
12429
12430 PyMem_Free(path_strW);
12431
12432 if (iterator->handle == INVALID_HANDLE_VALUE) {
12433 path_error(&iterator->path);
12434 goto error;
12435 }
12436#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012437 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012438#ifdef HAVE_FDOPENDIR
12439 if (path->fd != -1) {
12440 /* closedir() closes the FD, so we duplicate it */
12441 fd = _Py_dup(path->fd);
12442 if (fd == -1)
12443 goto error;
12444
12445 Py_BEGIN_ALLOW_THREADS
12446 iterator->dirp = fdopendir(fd);
12447 Py_END_ALLOW_THREADS
12448 }
12449 else
12450#endif
12451 {
12452 if (iterator->path.narrow)
12453 path_str = iterator->path.narrow;
12454 else
12455 path_str = ".";
12456
12457 Py_BEGIN_ALLOW_THREADS
12458 iterator->dirp = opendir(path_str);
12459 Py_END_ALLOW_THREADS
12460 }
Victor Stinner6036e442015-03-08 01:58:04 +010012461
12462 if (!iterator->dirp) {
12463 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012464#ifdef HAVE_FDOPENDIR
12465 if (fd != -1) {
12466 Py_BEGIN_ALLOW_THREADS
12467 close(fd);
12468 Py_END_ALLOW_THREADS
12469 }
12470#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012471 goto error;
12472 }
12473#endif
12474
12475 return (PyObject *)iterator;
12476
12477error:
12478 Py_DECREF(iterator);
12479 return NULL;
12480}
12481
Ethan Furman410ef8e2016-06-04 12:06:26 -070012482/*
12483 Return the file system path representation of the object.
12484
12485 If the object is str or bytes, then allow it to pass through with
12486 an incremented refcount. If the object defines __fspath__(), then
12487 return the result of that method. All other types raise a TypeError.
12488*/
12489PyObject *
12490PyOS_FSPath(PyObject *path)
12491{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012492 /* For error message reasons, this function is manually inlined in
12493 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012494 _Py_IDENTIFIER(__fspath__);
12495 PyObject *func = NULL;
12496 PyObject *path_repr = NULL;
12497
12498 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12499 Py_INCREF(path);
12500 return path;
12501 }
12502
12503 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12504 if (NULL == func) {
12505 return PyErr_Format(PyExc_TypeError,
12506 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012507 "not %.200s",
12508 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012509 }
12510
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012511 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012512 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012513 if (NULL == path_repr) {
12514 return NULL;
12515 }
12516
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012517 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12518 PyErr_Format(PyExc_TypeError,
12519 "expected %.200s.__fspath__() to return str or bytes, "
12520 "not %.200s", Py_TYPE(path)->tp_name,
12521 Py_TYPE(path_repr)->tp_name);
12522 Py_DECREF(path_repr);
12523 return NULL;
12524 }
12525
Ethan Furman410ef8e2016-06-04 12:06:26 -070012526 return path_repr;
12527}
12528
12529/*[clinic input]
12530os.fspath
12531
12532 path: object
12533
12534Return the file system path representation of the object.
12535
Brett Cannonb4f43e92016-06-09 14:32:08 -070012536If the object is str or bytes, then allow it to pass through as-is. If the
12537object defines __fspath__(), then return the result of that method. All other
12538types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012539[clinic start generated code]*/
12540
12541static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012542os_fspath_impl(PyObject *module, PyObject *path)
12543/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012544{
12545 return PyOS_FSPath(path);
12546}
Victor Stinner6036e442015-03-08 01:58:04 +010012547
Victor Stinner9b1f4742016-09-06 16:18:52 -070012548#ifdef HAVE_GETRANDOM_SYSCALL
12549/*[clinic input]
12550os.getrandom
12551
12552 size: Py_ssize_t
12553 flags: int=0
12554
12555Obtain a series of random bytes.
12556[clinic start generated code]*/
12557
12558static PyObject *
12559os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12560/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12561{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012562 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012563 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012564
12565 if (size < 0) {
12566 errno = EINVAL;
12567 return posix_error();
12568 }
12569
Victor Stinnerec2319c2016-09-20 23:00:59 +020012570 bytes = PyBytes_FromStringAndSize(NULL, size);
12571 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012572 PyErr_NoMemory();
12573 return NULL;
12574 }
12575
12576 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012577 n = syscall(SYS_getrandom,
12578 PyBytes_AS_STRING(bytes),
12579 PyBytes_GET_SIZE(bytes),
12580 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012581 if (n < 0 && errno == EINTR) {
12582 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012583 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012584 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012585
12586 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012587 continue;
12588 }
12589 break;
12590 }
12591
12592 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012593 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012594 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012595 }
12596
Victor Stinnerec2319c2016-09-20 23:00:59 +020012597 if (n != size) {
12598 _PyBytes_Resize(&bytes, n);
12599 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012600
12601 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012602
12603error:
12604 Py_DECREF(bytes);
12605 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012606}
12607#endif /* HAVE_GETRANDOM_SYSCALL */
12608
Larry Hastings31826802013-10-19 00:09:25 -070012609
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012610static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012611
12612 OS_STAT_METHODDEF
12613 OS_ACCESS_METHODDEF
12614 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012615 OS_CHDIR_METHODDEF
12616 OS_CHFLAGS_METHODDEF
12617 OS_CHMOD_METHODDEF
12618 OS_FCHMOD_METHODDEF
12619 OS_LCHMOD_METHODDEF
12620 OS_CHOWN_METHODDEF
12621 OS_FCHOWN_METHODDEF
12622 OS_LCHOWN_METHODDEF
12623 OS_LCHFLAGS_METHODDEF
12624 OS_CHROOT_METHODDEF
12625 OS_CTERMID_METHODDEF
12626 OS_GETCWD_METHODDEF
12627 OS_GETCWDB_METHODDEF
12628 OS_LINK_METHODDEF
12629 OS_LISTDIR_METHODDEF
12630 OS_LSTAT_METHODDEF
12631 OS_MKDIR_METHODDEF
12632 OS_NICE_METHODDEF
12633 OS_GETPRIORITY_METHODDEF
12634 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012635#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012636 {"readlink", (PyCFunction)posix_readlink,
12637 METH_VARARGS | METH_KEYWORDS,
12638 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012639#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012640#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012641 {"readlink", (PyCFunction)win_readlink,
12642 METH_VARARGS | METH_KEYWORDS,
12643 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012644#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012645 OS_RENAME_METHODDEF
12646 OS_REPLACE_METHODDEF
12647 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012648 OS_SYMLINK_METHODDEF
12649 OS_SYSTEM_METHODDEF
12650 OS_UMASK_METHODDEF
12651 OS_UNAME_METHODDEF
12652 OS_UNLINK_METHODDEF
12653 OS_REMOVE_METHODDEF
12654 OS_UTIME_METHODDEF
12655 OS_TIMES_METHODDEF
12656 OS__EXIT_METHODDEF
12657 OS_EXECV_METHODDEF
12658 OS_EXECVE_METHODDEF
12659 OS_SPAWNV_METHODDEF
12660 OS_SPAWNVE_METHODDEF
12661 OS_FORK1_METHODDEF
12662 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012663 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012664 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12665 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12666 OS_SCHED_GETPARAM_METHODDEF
12667 OS_SCHED_GETSCHEDULER_METHODDEF
12668 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12669 OS_SCHED_SETPARAM_METHODDEF
12670 OS_SCHED_SETSCHEDULER_METHODDEF
12671 OS_SCHED_YIELD_METHODDEF
12672 OS_SCHED_SETAFFINITY_METHODDEF
12673 OS_SCHED_GETAFFINITY_METHODDEF
12674 OS_OPENPTY_METHODDEF
12675 OS_FORKPTY_METHODDEF
12676 OS_GETEGID_METHODDEF
12677 OS_GETEUID_METHODDEF
12678 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012679#ifdef HAVE_GETGROUPLIST
12680 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12681#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012682 OS_GETGROUPS_METHODDEF
12683 OS_GETPID_METHODDEF
12684 OS_GETPGRP_METHODDEF
12685 OS_GETPPID_METHODDEF
12686 OS_GETUID_METHODDEF
12687 OS_GETLOGIN_METHODDEF
12688 OS_KILL_METHODDEF
12689 OS_KILLPG_METHODDEF
12690 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012691#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012692 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012693#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012694 OS_SETUID_METHODDEF
12695 OS_SETEUID_METHODDEF
12696 OS_SETREUID_METHODDEF
12697 OS_SETGID_METHODDEF
12698 OS_SETEGID_METHODDEF
12699 OS_SETREGID_METHODDEF
12700 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012701#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012702 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012703#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012704 OS_GETPGID_METHODDEF
12705 OS_SETPGRP_METHODDEF
12706 OS_WAIT_METHODDEF
12707 OS_WAIT3_METHODDEF
12708 OS_WAIT4_METHODDEF
12709 OS_WAITID_METHODDEF
12710 OS_WAITPID_METHODDEF
12711 OS_GETSID_METHODDEF
12712 OS_SETSID_METHODDEF
12713 OS_SETPGID_METHODDEF
12714 OS_TCGETPGRP_METHODDEF
12715 OS_TCSETPGRP_METHODDEF
12716 OS_OPEN_METHODDEF
12717 OS_CLOSE_METHODDEF
12718 OS_CLOSERANGE_METHODDEF
12719 OS_DEVICE_ENCODING_METHODDEF
12720 OS_DUP_METHODDEF
12721 OS_DUP2_METHODDEF
12722 OS_LOCKF_METHODDEF
12723 OS_LSEEK_METHODDEF
12724 OS_READ_METHODDEF
12725 OS_READV_METHODDEF
12726 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012727 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012728 OS_WRITE_METHODDEF
12729 OS_WRITEV_METHODDEF
12730 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012731 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012732#ifdef HAVE_SENDFILE
12733 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12734 posix_sendfile__doc__},
12735#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012736 OS_FSTAT_METHODDEF
12737 OS_ISATTY_METHODDEF
12738 OS_PIPE_METHODDEF
12739 OS_PIPE2_METHODDEF
12740 OS_MKFIFO_METHODDEF
12741 OS_MKNOD_METHODDEF
12742 OS_MAJOR_METHODDEF
12743 OS_MINOR_METHODDEF
12744 OS_MAKEDEV_METHODDEF
12745 OS_FTRUNCATE_METHODDEF
12746 OS_TRUNCATE_METHODDEF
12747 OS_POSIX_FALLOCATE_METHODDEF
12748 OS_POSIX_FADVISE_METHODDEF
12749 OS_PUTENV_METHODDEF
12750 OS_UNSETENV_METHODDEF
12751 OS_STRERROR_METHODDEF
12752 OS_FCHDIR_METHODDEF
12753 OS_FSYNC_METHODDEF
12754 OS_SYNC_METHODDEF
12755 OS_FDATASYNC_METHODDEF
12756 OS_WCOREDUMP_METHODDEF
12757 OS_WIFCONTINUED_METHODDEF
12758 OS_WIFSTOPPED_METHODDEF
12759 OS_WIFSIGNALED_METHODDEF
12760 OS_WIFEXITED_METHODDEF
12761 OS_WEXITSTATUS_METHODDEF
12762 OS_WTERMSIG_METHODDEF
12763 OS_WSTOPSIG_METHODDEF
12764 OS_FSTATVFS_METHODDEF
12765 OS_STATVFS_METHODDEF
12766 OS_CONFSTR_METHODDEF
12767 OS_SYSCONF_METHODDEF
12768 OS_FPATHCONF_METHODDEF
12769 OS_PATHCONF_METHODDEF
12770 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012771 OS__GETFULLPATHNAME_METHODDEF
12772 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012773 OS__GETDISKUSAGE_METHODDEF
12774 OS__GETFINALPATHNAME_METHODDEF
12775 OS__GETVOLUMEPATHNAME_METHODDEF
12776 OS_GETLOADAVG_METHODDEF
12777 OS_URANDOM_METHODDEF
12778 OS_SETRESUID_METHODDEF
12779 OS_SETRESGID_METHODDEF
12780 OS_GETRESUID_METHODDEF
12781 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012782
Larry Hastings2f936352014-08-05 14:04:04 +100012783 OS_GETXATTR_METHODDEF
12784 OS_SETXATTR_METHODDEF
12785 OS_REMOVEXATTR_METHODDEF
12786 OS_LISTXATTR_METHODDEF
12787
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012788#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12789 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12790#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012791 OS_CPU_COUNT_METHODDEF
12792 OS_GET_INHERITABLE_METHODDEF
12793 OS_SET_INHERITABLE_METHODDEF
12794 OS_GET_HANDLE_INHERITABLE_METHODDEF
12795 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012796#ifndef MS_WINDOWS
12797 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12798 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12799#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012800 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012801 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012802 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012803 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012804};
12805
12806
Brian Curtin52173d42010-12-02 18:29:18 +000012807#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012808static int
Brian Curtin52173d42010-12-02 18:29:18 +000012809enable_symlink()
12810{
12811 HANDLE tok;
12812 TOKEN_PRIVILEGES tok_priv;
12813 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012814
12815 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012816 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012817
12818 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012819 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012820
12821 tok_priv.PrivilegeCount = 1;
12822 tok_priv.Privileges[0].Luid = luid;
12823 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12824
12825 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12826 sizeof(TOKEN_PRIVILEGES),
12827 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012828 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012829
Brian Curtin3b4499c2010-12-28 14:31:47 +000012830 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12831 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012832}
12833#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12834
Barry Warsaw4a342091996-12-19 23:50:02 +000012835static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012836all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012837{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012838#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012839 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012840#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012841#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012843#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012844#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012846#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012847#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012849#endif
Fred Drakec9680921999-12-13 16:37:25 +000012850#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012852#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012853#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012855#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012856#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012858#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012859#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012861#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012862#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012863 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012864#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012865#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012867#endif
12868#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012870#endif
12871#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012873#endif
12874#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012876#endif
12877#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012879#endif
12880#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012882#endif
12883#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012885#endif
12886#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012888#endif
12889#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012891#endif
12892#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012894#endif
12895#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012897#endif
12898#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012900#endif
12901#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012903#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012904#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012906#endif
12907#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012909#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012910#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012911 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012912#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012913#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012915#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012916#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012917#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012918 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012919#endif
12920#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012922#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012923#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012924#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012925 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012926#endif
12927#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012928 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012929#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012930#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012931 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012932#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012933#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012934 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012935#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012936#ifdef O_TMPFILE
12937 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12938#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012939#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012941#endif
12942#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012943 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012944#endif
12945#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012947#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012948#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012950#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012951#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012953#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012954
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012955
Jesus Cea94363612012-06-22 18:32:07 +020012956#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012957 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012958#endif
12959#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012961#endif
12962
Tim Peters5aa91602002-01-30 05:46:57 +000012963/* MS Windows */
12964#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012965 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012966 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012967#endif
12968#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 /* Optimize for short life (keep in memory). */
12970 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012971 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012972#endif
12973#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012974 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012975 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012976#endif
12977#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012978 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012980#endif
12981#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012983 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012984#endif
12985
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012986/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012987#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012988 /* Send a SIGIO signal whenever input or output
12989 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012991#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012992#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012993 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012994 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012995#endif
12996#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012998 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012999#endif
13000#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013002 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013003#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013004#ifdef O_NOLINKS
13005 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013007#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013008#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013009 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013010 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013011#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013012
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013014#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013016#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013017#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013019#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013020#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013022#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013023#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013024 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013025#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013026#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013027 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013028#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013029#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013030 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013031#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013032#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013033 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013034#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013035#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013036 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013037#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013038#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013039 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013040#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013041#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013042 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013043#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013044#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013046#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013047#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013048 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013049#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013050#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013051 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013052#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013053#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013054 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013055#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013056#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013057 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013058#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013059#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013060 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013061#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013062#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013063 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013064#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013065
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013066 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013067#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013068 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013069#endif /* ST_RDONLY */
13070#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013071 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013072#endif /* ST_NOSUID */
13073
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013074 /* GNU extensions */
13075#ifdef ST_NODEV
13076 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13077#endif /* ST_NODEV */
13078#ifdef ST_NOEXEC
13079 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13080#endif /* ST_NOEXEC */
13081#ifdef ST_SYNCHRONOUS
13082 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13083#endif /* ST_SYNCHRONOUS */
13084#ifdef ST_MANDLOCK
13085 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13086#endif /* ST_MANDLOCK */
13087#ifdef ST_WRITE
13088 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13089#endif /* ST_WRITE */
13090#ifdef ST_APPEND
13091 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13092#endif /* ST_APPEND */
13093#ifdef ST_NOATIME
13094 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13095#endif /* ST_NOATIME */
13096#ifdef ST_NODIRATIME
13097 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13098#endif /* ST_NODIRATIME */
13099#ifdef ST_RELATIME
13100 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13101#endif /* ST_RELATIME */
13102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013103 /* FreeBSD sendfile() constants */
13104#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013105 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013106#endif
13107#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013108 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013109#endif
13110#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013111 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013112#endif
13113
Ross Lagerwall7807c352011-03-17 20:20:30 +020013114 /* constants for posix_fadvise */
13115#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013116 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013117#endif
13118#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013119 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013120#endif
13121#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013122 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013123#endif
13124#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013125 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013126#endif
13127#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013128 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013129#endif
13130#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013131 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013132#endif
13133
13134 /* constants for waitid */
13135#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013136 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13137 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13138 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013139#endif
13140#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013141 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013142#endif
13143#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013144 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013145#endif
13146#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013147 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013148#endif
13149#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013150 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013151#endif
13152#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013153 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013154#endif
13155#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013156 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013157#endif
13158#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013159 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013160#endif
13161
13162 /* constants for lockf */
13163#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013164 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013165#endif
13166#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013167 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013168#endif
13169#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013170 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013171#endif
13172#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013173 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013174#endif
13175
Pablo Galindo4defba32018-01-27 16:16:37 +000013176#ifdef RWF_DSYNC
13177 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13178#endif
13179#ifdef RWF_HIPRI
13180 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13181#endif
13182#ifdef RWF_SYNC
13183 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13184#endif
13185#ifdef RWF_NOWAIT
13186 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13187#endif
13188
Guido van Rossum246bc171999-02-01 23:54:31 +000013189#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013190 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13191 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13192 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13193 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13194 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013195#endif
13196
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013197#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013198#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013199 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013200#endif
13201#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013202 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013203#endif
13204#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013205 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013206#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013207#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013208 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013209#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013210#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013211 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013212#endif
13213#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013214 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013215#endif
13216#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013217 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013218#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013219#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013220 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013221#endif
13222#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013223 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013224#endif
13225#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013226 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013227#endif
13228#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013229 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013230#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013231#endif
13232
Benjamin Peterson9428d532011-09-14 11:45:52 -040013233#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013234 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13235 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13236 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013237#endif
13238
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013239#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013240 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013241#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013242#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013243 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013244#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013245#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013246 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013247#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013248#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013249 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013250#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013251#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013252 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013253#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013254#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013255 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013256#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013257#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013258 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013259#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013260#if HAVE_DECL_RTLD_MEMBER
13261 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13262#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013263
Victor Stinner9b1f4742016-09-06 16:18:52 -070013264#ifdef HAVE_GETRANDOM_SYSCALL
13265 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13266 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13267#endif
13268
Victor Stinner8c62be82010-05-06 00:08:46 +000013269 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013270}
13271
13272
Martin v. Löwis1a214512008-06-11 05:26:20 +000013273static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013274 PyModuleDef_HEAD_INIT,
13275 MODNAME,
13276 posix__doc__,
13277 -1,
13278 posix_methods,
13279 NULL,
13280 NULL,
13281 NULL,
13282 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013283};
13284
13285
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013286static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013287
13288#ifdef HAVE_FACCESSAT
13289 "HAVE_FACCESSAT",
13290#endif
13291
13292#ifdef HAVE_FCHDIR
13293 "HAVE_FCHDIR",
13294#endif
13295
13296#ifdef HAVE_FCHMOD
13297 "HAVE_FCHMOD",
13298#endif
13299
13300#ifdef HAVE_FCHMODAT
13301 "HAVE_FCHMODAT",
13302#endif
13303
13304#ifdef HAVE_FCHOWN
13305 "HAVE_FCHOWN",
13306#endif
13307
Larry Hastings00964ed2013-08-12 13:49:30 -040013308#ifdef HAVE_FCHOWNAT
13309 "HAVE_FCHOWNAT",
13310#endif
13311
Larry Hastings9cf065c2012-06-22 16:30:09 -070013312#ifdef HAVE_FEXECVE
13313 "HAVE_FEXECVE",
13314#endif
13315
13316#ifdef HAVE_FDOPENDIR
13317 "HAVE_FDOPENDIR",
13318#endif
13319
Georg Brandl306336b2012-06-24 12:55:33 +020013320#ifdef HAVE_FPATHCONF
13321 "HAVE_FPATHCONF",
13322#endif
13323
Larry Hastings9cf065c2012-06-22 16:30:09 -070013324#ifdef HAVE_FSTATAT
13325 "HAVE_FSTATAT",
13326#endif
13327
13328#ifdef HAVE_FSTATVFS
13329 "HAVE_FSTATVFS",
13330#endif
13331
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013332#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013333 "HAVE_FTRUNCATE",
13334#endif
13335
Larry Hastings9cf065c2012-06-22 16:30:09 -070013336#ifdef HAVE_FUTIMENS
13337 "HAVE_FUTIMENS",
13338#endif
13339
13340#ifdef HAVE_FUTIMES
13341 "HAVE_FUTIMES",
13342#endif
13343
13344#ifdef HAVE_FUTIMESAT
13345 "HAVE_FUTIMESAT",
13346#endif
13347
13348#ifdef HAVE_LINKAT
13349 "HAVE_LINKAT",
13350#endif
13351
13352#ifdef HAVE_LCHFLAGS
13353 "HAVE_LCHFLAGS",
13354#endif
13355
13356#ifdef HAVE_LCHMOD
13357 "HAVE_LCHMOD",
13358#endif
13359
13360#ifdef HAVE_LCHOWN
13361 "HAVE_LCHOWN",
13362#endif
13363
13364#ifdef HAVE_LSTAT
13365 "HAVE_LSTAT",
13366#endif
13367
13368#ifdef HAVE_LUTIMES
13369 "HAVE_LUTIMES",
13370#endif
13371
13372#ifdef HAVE_MKDIRAT
13373 "HAVE_MKDIRAT",
13374#endif
13375
13376#ifdef HAVE_MKFIFOAT
13377 "HAVE_MKFIFOAT",
13378#endif
13379
13380#ifdef HAVE_MKNODAT
13381 "HAVE_MKNODAT",
13382#endif
13383
13384#ifdef HAVE_OPENAT
13385 "HAVE_OPENAT",
13386#endif
13387
13388#ifdef HAVE_READLINKAT
13389 "HAVE_READLINKAT",
13390#endif
13391
13392#ifdef HAVE_RENAMEAT
13393 "HAVE_RENAMEAT",
13394#endif
13395
13396#ifdef HAVE_SYMLINKAT
13397 "HAVE_SYMLINKAT",
13398#endif
13399
13400#ifdef HAVE_UNLINKAT
13401 "HAVE_UNLINKAT",
13402#endif
13403
13404#ifdef HAVE_UTIMENSAT
13405 "HAVE_UTIMENSAT",
13406#endif
13407
13408#ifdef MS_WINDOWS
13409 "MS_WINDOWS",
13410#endif
13411
13412 NULL
13413};
13414
13415
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013416PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013417INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013418{
Victor Stinner8c62be82010-05-06 00:08:46 +000013419 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013420 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013421 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013422
Brian Curtin52173d42010-12-02 18:29:18 +000013423#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013424 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013425#endif
13426
Victor Stinner8c62be82010-05-06 00:08:46 +000013427 m = PyModule_Create(&posixmodule);
13428 if (m == NULL)
13429 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013430
Victor Stinner8c62be82010-05-06 00:08:46 +000013431 /* Initialize environ dictionary */
13432 v = convertenviron();
13433 Py_XINCREF(v);
13434 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13435 return NULL;
13436 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013437
Victor Stinner8c62be82010-05-06 00:08:46 +000013438 if (all_ins(m))
13439 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013440
Victor Stinner8c62be82010-05-06 00:08:46 +000013441 if (setup_confname_tables(m))
13442 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013443
Victor Stinner8c62be82010-05-06 00:08:46 +000013444 Py_INCREF(PyExc_OSError);
13445 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013446
Guido van Rossumb3d39562000-01-31 18:41:26 +000013447#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013448 if (posix_putenv_garbage == NULL)
13449 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013450#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013451
Victor Stinner8c62be82010-05-06 00:08:46 +000013452 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013453#if defined(HAVE_WAITID) && !defined(__APPLE__)
13454 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013455 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13456 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013457#endif
13458
Christian Heimes25827622013-10-12 01:27:08 +020013459 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013460 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13461 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13462 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013463 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13464 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013465 structseq_new = StatResultType.tp_new;
13466 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013467
Christian Heimes25827622013-10-12 01:27:08 +020013468 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013469 if (PyStructSequence_InitType2(&StatVFSResultType,
13470 &statvfs_result_desc) < 0)
13471 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013472#ifdef NEED_TICKS_PER_SECOND
13473# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013474 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013475# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013476 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013477# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013478 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013479# endif
13480#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013481
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013482#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013483 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013484 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13485 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013486 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013487#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013488
13489 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013490 if (PyStructSequence_InitType2(&TerminalSizeType,
13491 &TerminalSize_desc) < 0)
13492 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013493
13494 /* initialize scandir types */
13495 if (PyType_Ready(&ScandirIteratorType) < 0)
13496 return NULL;
13497 if (PyType_Ready(&DirEntryType) < 0)
13498 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013499 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013500#if defined(HAVE_WAITID) && !defined(__APPLE__)
13501 Py_INCREF((PyObject*) &WaitidResultType);
13502 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13503#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013504 Py_INCREF((PyObject*) &StatResultType);
13505 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13506 Py_INCREF((PyObject*) &StatVFSResultType);
13507 PyModule_AddObject(m, "statvfs_result",
13508 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013509
13510#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013511 Py_INCREF(&SchedParamType);
13512 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013513#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013514
Larry Hastings605a62d2012-06-24 04:33:36 -070013515 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013516 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13517 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013518 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13519
13520 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013521 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13522 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013523 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13524
Thomas Wouters477c8d52006-05-27 19:21:47 +000013525#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013526 /*
13527 * Step 2 of weak-linking support on Mac OS X.
13528 *
13529 * The code below removes functions that are not available on the
13530 * currently active platform.
13531 *
13532 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013533 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013534 * OSX 10.4.
13535 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013536#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013537 if (fstatvfs == NULL) {
13538 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13539 return NULL;
13540 }
13541 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013542#endif /* HAVE_FSTATVFS */
13543
13544#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013545 if (statvfs == NULL) {
13546 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13547 return NULL;
13548 }
13549 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013550#endif /* HAVE_STATVFS */
13551
13552# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013553 if (lchown == NULL) {
13554 if (PyObject_DelAttrString(m, "lchown") == -1) {
13555 return NULL;
13556 }
13557 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013558#endif /* HAVE_LCHOWN */
13559
13560
13561#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013562
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013563 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013564 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13565
Larry Hastings6fe20b32012-04-19 15:07:49 -070013566 billion = PyLong_FromLong(1000000000);
13567 if (!billion)
13568 return NULL;
13569
Larry Hastings9cf065c2012-06-22 16:30:09 -070013570 /* suppress "function not used" warnings */
13571 {
13572 int ignored;
13573 fd_specified("", -1);
13574 follow_symlinks_specified("", 1);
13575 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13576 dir_fd_converter(Py_None, &ignored);
13577 dir_fd_unavailable(Py_None, &ignored);
13578 }
13579
13580 /*
13581 * provide list of locally available functions
13582 * so os.py can populate support_* lists
13583 */
13584 list = PyList_New(0);
13585 if (!list)
13586 return NULL;
13587 for (trace = have_functions; *trace; trace++) {
13588 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13589 if (!unicode)
13590 return NULL;
13591 if (PyList_Append(list, unicode))
13592 return NULL;
13593 Py_DECREF(unicode);
13594 }
13595 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013596
13597 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013598 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013599
13600 initialized = 1;
13601
Victor Stinner8c62be82010-05-06 00:08:46 +000013602 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013603}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013604
13605#ifdef __cplusplus
13606}
13607#endif