blob: de32327b30402ac23cbc93dd4f769125903c00c4 [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 VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
305#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000306#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000307#endif
308#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000309#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000310#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100311#ifndef IO_REPARSE_TAG_MOUNT_POINT
312#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
313#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000315#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000316#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000317#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000318#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000319#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
320#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000321static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000322#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000323#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000324
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000326#if defined(PATH_MAX) && PATH_MAX > 1024
327#define MAXPATHLEN PATH_MAX
328#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#endif /* MAXPATHLEN */
332
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000333#ifdef UNION_WAIT
334/* Emulate some macros on systems that have a union instead of macros */
335
336#ifndef WIFEXITED
337#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
338#endif
339
340#ifndef WEXITSTATUS
341#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
342#endif
343
344#ifndef WTERMSIG
345#define WTERMSIG(u_wait) ((u_wait).w_termsig)
346#endif
347
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000348#define WAIT_TYPE union wait
349#define WAIT_STATUS_INT(s) (s.w_status)
350
351#else /* !UNION_WAIT */
352#define WAIT_TYPE int
353#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000354#endif /* UNION_WAIT */
355
Greg Wardb48bc172000-03-01 21:51:56 +0000356/* Don't use the "_r" form if we don't need it (also, won't have a
357 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200358#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000359#define USE_CTERMID_R
360#endif
361
Fred Drake699f3522000-06-29 21:12:41 +0000362/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000363#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000364#undef FSTAT
365#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200366#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700368# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200369# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800370# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000371#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000372# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700373# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define FSTAT fstat
375# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000376#endif
377
Tim Peters11b23062003-04-23 02:39:17 +0000378#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000379#include <sys/mkdev.h>
380#else
381#if defined(MAJOR_IN_SYSMACROS)
382#include <sys/sysmacros.h>
383#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000384#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
385#include <sys/mkdev.h>
386#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000387#endif
Fred Drake699f3522000-06-29 21:12:41 +0000388
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200389#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100390#define INITFUNC PyInit_nt
391#define MODNAME "nt"
392#else
393#define INITFUNC PyInit_posix
394#define MODNAME "posix"
395#endif
396
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200397
398#ifdef HAVE_FORK
399static void
400run_at_forkers(PyObject *lst, int reverse)
401{
402 Py_ssize_t i;
403 PyObject *cpy;
404
405 if (lst != NULL) {
406 assert(PyList_CheckExact(lst));
407
408 /* Use a list copy in case register_at_fork() is called from
409 * one of the callbacks.
410 */
411 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
412 if (cpy == NULL)
413 PyErr_WriteUnraisable(lst);
414 else {
415 if (reverse)
416 PyList_Reverse(cpy);
417 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
418 PyObject *func, *res;
419 func = PyList_GET_ITEM(cpy, i);
420 res = PyObject_CallObject(func, NULL);
421 if (res == NULL)
422 PyErr_WriteUnraisable(func);
423 else
424 Py_DECREF(res);
425 }
426 Py_DECREF(cpy);
427 }
428 }
429}
430
431void
432PyOS_BeforeFork(void)
433{
434 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
435
436 _PyImport_AcquireLock();
437}
438
439void
440PyOS_AfterFork_Parent(void)
441{
442 if (_PyImport_ReleaseLock() <= 0)
443 Py_FatalError("failed releasing import lock after fork");
444
445 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
446}
447
448void
449PyOS_AfterFork_Child(void)
450{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200451 _PyGILState_Reinit();
452 PyEval_ReInitThreads();
453 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200454 _PySignal_AfterFork();
455
456 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
457}
458
459static int
460register_at_forker(PyObject **lst, PyObject *func)
461{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700462 if (func == NULL) /* nothing to register? do nothing. */
463 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200464 if (*lst == NULL) {
465 *lst = PyList_New(0);
466 if (*lst == NULL)
467 return -1;
468 }
469 return PyList_Append(*lst, func);
470}
471#endif
472
473/* Legacy wrapper */
474void
475PyOS_AfterFork(void)
476{
477#ifdef HAVE_FORK
478 PyOS_AfterFork_Child();
479#endif
480}
481
482
Victor Stinner6036e442015-03-08 01:58:04 +0100483#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200484/* defined in fileutils.c */
485PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
486PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
487 ULONG, struct _Py_stat_struct *);
488#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700489
490#ifdef MS_WINDOWS
491static int
492win32_warn_bytes_api()
493{
494 return PyErr_WarnEx(PyExc_DeprecationWarning,
495 "The Windows bytes API has been deprecated, "
496 "use Unicode filenames instead",
497 1);
498}
499#endif
500
501
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200502#ifndef MS_WINDOWS
503PyObject *
504_PyLong_FromUid(uid_t uid)
505{
506 if (uid == (uid_t)-1)
507 return PyLong_FromLong(-1);
508 return PyLong_FromUnsignedLong(uid);
509}
510
511PyObject *
512_PyLong_FromGid(gid_t gid)
513{
514 if (gid == (gid_t)-1)
515 return PyLong_FromLong(-1);
516 return PyLong_FromUnsignedLong(gid);
517}
518
519int
520_Py_Uid_Converter(PyObject *obj, void *p)
521{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700522 uid_t uid;
523 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200524 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200525 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 unsigned long uresult;
527
528 index = PyNumber_Index(obj);
529 if (index == NULL) {
530 PyErr_Format(PyExc_TypeError,
531 "uid should be integer, not %.200s",
532 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200533 return 0;
534 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535
536 /*
537 * Handling uid_t is complicated for two reasons:
538 * * Although uid_t is (always?) unsigned, it still
539 * accepts -1.
540 * * We don't know its size in advance--it may be
541 * bigger than an int, or it may be smaller than
542 * a long.
543 *
544 * So a bit of defensive programming is in order.
545 * Start with interpreting the value passed
546 * in as a signed long and see if it works.
547 */
548
549 result = PyLong_AsLongAndOverflow(index, &overflow);
550
551 if (!overflow) {
552 uid = (uid_t)result;
553
554 if (result == -1) {
555 if (PyErr_Occurred())
556 goto fail;
557 /* It's a legitimate -1, we're done. */
558 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200559 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700560
561 /* Any other negative number is disallowed. */
562 if (result < 0)
563 goto underflow;
564
565 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200566 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700567 (long)uid != result)
568 goto underflow;
569 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200570 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700571
572 if (overflow < 0)
573 goto underflow;
574
575 /*
576 * Okay, the value overflowed a signed long. If it
577 * fits in an *unsigned* long, it may still be okay,
578 * as uid_t may be unsigned long on this platform.
579 */
580 uresult = PyLong_AsUnsignedLong(index);
581 if (PyErr_Occurred()) {
582 if (PyErr_ExceptionMatches(PyExc_OverflowError))
583 goto overflow;
584 goto fail;
585 }
586
587 uid = (uid_t)uresult;
588
589 /*
590 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
591 * but this value would get interpreted as (uid_t)-1 by chown
592 * and its siblings. That's not what the user meant! So we
593 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100594 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700595 */
596 if (uid == (uid_t)-1)
597 goto overflow;
598
599 /* Ensure the value wasn't truncated. */
600 if (sizeof(uid_t) < sizeof(long) &&
601 (unsigned long)uid != uresult)
602 goto overflow;
603 /* fallthrough */
604
605success:
606 Py_DECREF(index);
607 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200608 return 1;
609
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700610underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200611 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700612 "uid is less than minimum");
613 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700617 "uid is greater than maximum");
618 /* fallthrough */
619
620fail:
621 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622 return 0;
623}
624
625int
626_Py_Gid_Converter(PyObject *obj, void *p)
627{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700628 gid_t gid;
629 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200631 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700632 unsigned long uresult;
633
634 index = PyNumber_Index(obj);
635 if (index == NULL) {
636 PyErr_Format(PyExc_TypeError,
637 "gid should be integer, not %.200s",
638 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200639 return 0;
640 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700641
642 /*
643 * Handling gid_t is complicated for two reasons:
644 * * Although gid_t is (always?) unsigned, it still
645 * accepts -1.
646 * * We don't know its size in advance--it may be
647 * bigger than an int, or it may be smaller than
648 * a long.
649 *
650 * So a bit of defensive programming is in order.
651 * Start with interpreting the value passed
652 * in as a signed long and see if it works.
653 */
654
655 result = PyLong_AsLongAndOverflow(index, &overflow);
656
657 if (!overflow) {
658 gid = (gid_t)result;
659
660 if (result == -1) {
661 if (PyErr_Occurred())
662 goto fail;
663 /* It's a legitimate -1, we're done. */
664 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200665 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666
667 /* Any other negative number is disallowed. */
668 if (result < 0) {
669 goto underflow;
670 }
671
672 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200673 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700674 (long)gid != result)
675 goto underflow;
676 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200677 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700678
679 if (overflow < 0)
680 goto underflow;
681
682 /*
683 * Okay, the value overflowed a signed long. If it
684 * fits in an *unsigned* long, it may still be okay,
685 * as gid_t may be unsigned long on this platform.
686 */
687 uresult = PyLong_AsUnsignedLong(index);
688 if (PyErr_Occurred()) {
689 if (PyErr_ExceptionMatches(PyExc_OverflowError))
690 goto overflow;
691 goto fail;
692 }
693
694 gid = (gid_t)uresult;
695
696 /*
697 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
698 * but this value would get interpreted as (gid_t)-1 by chown
699 * and its siblings. That's not what the user meant! So we
700 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100701 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700702 */
703 if (gid == (gid_t)-1)
704 goto overflow;
705
706 /* Ensure the value wasn't truncated. */
707 if (sizeof(gid_t) < sizeof(long) &&
708 (unsigned long)gid != uresult)
709 goto overflow;
710 /* fallthrough */
711
712success:
713 Py_DECREF(index);
714 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200715 return 1;
716
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700717underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200718 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700719 "gid is less than minimum");
720 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700722overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200723 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700724 "gid is greater than maximum");
725 /* fallthrough */
726
727fail:
728 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 return 0;
730}
731#endif /* MS_WINDOWS */
732
733
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700734#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800735
736
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200737#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
738static int
739_Py_Dev_Converter(PyObject *obj, void *p)
740{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200741 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200742 if (PyErr_Occurred())
743 return 0;
744 return 1;
745}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800746#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200747
748
Larry Hastings9cf065c2012-06-22 16:30:09 -0700749#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400750/*
751 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
752 * without the int cast, the value gets interpreted as uint (4291925331),
753 * which doesn't play nicely with all the initializer lines in this file that
754 * look like this:
755 * int dir_fd = DEFAULT_DIR_FD;
756 */
757#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700758#else
759#define DEFAULT_DIR_FD (-100)
760#endif
761
762static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300763_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200764{
765 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700766 long long_value;
767
768 PyObject *index = PyNumber_Index(o);
769 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700770 return 0;
771 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300773 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700774 long_value = PyLong_AsLongAndOverflow(index, &overflow);
775 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300776 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200777 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700778 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700779 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780 return 0;
781 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200782 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700784 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700785 return 0;
786 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700787
Larry Hastings9cf065c2012-06-22 16:30:09 -0700788 *p = (int)long_value;
789 return 1;
790}
791
792static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200793dir_fd_converter(PyObject *o, void *p)
794{
795 if (o == Py_None) {
796 *(int *)p = DEFAULT_DIR_FD;
797 return 1;
798 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300799 else if (PyIndex_Check(o)) {
800 return _fd_converter(o, (int *)p);
801 }
802 else {
803 PyErr_Format(PyExc_TypeError,
804 "argument should be integer or None, not %.200s",
805 Py_TYPE(o)->tp_name);
806 return 0;
807 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700808}
809
810
Larry Hastings9cf065c2012-06-22 16:30:09 -0700811/*
812 * A PyArg_ParseTuple "converter" function
813 * that handles filesystem paths in the manner
814 * preferred by the os module.
815 *
816 * path_converter accepts (Unicode) strings and their
817 * subclasses, and bytes and their subclasses. What
818 * it does with the argument depends on the platform:
819 *
820 * * On Windows, if we get a (Unicode) string we
821 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700822 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700823 *
824 * * On all other platforms, strings are encoded
825 * to bytes using PyUnicode_FSConverter, then we
826 * extract the char * from the bytes object and
827 * return that.
828 *
829 * path_converter also optionally accepts signed
830 * integers (representing open file descriptors) instead
831 * of path strings.
832 *
833 * Input fields:
834 * path.nullable
835 * If nonzero, the path is permitted to be None.
836 * path.allow_fd
837 * If nonzero, the path is permitted to be a file handle
838 * (a signed int) instead of a string.
839 * path.function_name
840 * If non-NULL, path_converter will use that as the name
841 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700842 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700843 * path.argument_name
844 * If non-NULL, path_converter will use that as the name
845 * of the parameter in error messages.
846 * (If path.argument_name is NULL it uses "path".)
847 *
848 * Output fields:
849 * path.wide
850 * Points to the path if it was expressed as Unicode
851 * and was not encoded. (Only used on Windows.)
852 * path.narrow
853 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700854 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000855 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700856 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700857 * path.fd
858 * Contains a file descriptor if path.accept_fd was true
859 * and the caller provided a signed integer instead of any
860 * sort of string.
861 *
862 * WARNING: if your "path" parameter is optional, and is
863 * unspecified, path_converter will never get called.
864 * So if you set allow_fd, you *MUST* initialize path.fd = -1
865 * yourself!
866 * path.length
867 * The length of the path in characters, if specified as
868 * a string.
869 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800870 * The original object passed in (if get a PathLike object,
871 * the result of PyOS_FSPath() is treated as the original object).
872 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873 * path.cleanup
874 * For internal use only. May point to a temporary object.
875 * (Pay no attention to the man behind the curtain.)
876 *
877 * At most one of path.wide or path.narrow will be non-NULL.
878 * If path was None and path.nullable was set,
879 * or if path was an integer and path.allow_fd was set,
880 * both path.wide and path.narrow will be NULL
881 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200882 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700883 * path_converter takes care to not write to the path_t
884 * unless it's successful. However it must reset the
885 * "cleanup" field each time it's called.
886 *
887 * Use as follows:
888 * path_t path;
889 * memset(&path, 0, sizeof(path));
890 * PyArg_ParseTuple(args, "O&", path_converter, &path);
891 * // ... use values from path ...
892 * path_cleanup(&path);
893 *
894 * (Note that if PyArg_Parse fails you don't need to call
895 * path_cleanup(). However it is safe to do so.)
896 */
897typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100898 const char *function_name;
899 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700900 int nullable;
901 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300902 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700903#ifdef MS_WINDOWS
904 BOOL narrow;
905#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300906 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700907#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 int fd;
909 Py_ssize_t length;
910 PyObject *object;
911 PyObject *cleanup;
912} path_t;
913
Steve Dowercc16be82016-09-08 10:35:16 -0700914#ifdef MS_WINDOWS
915#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
916 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
917#else
Larry Hastings2f936352014-08-05 14:04:04 +1000918#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
919 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700920#endif
Larry Hastings31826802013-10-19 00:09:25 -0700921
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800923path_cleanup(path_t *path)
924{
925 Py_CLEAR(path->object);
926 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700927}
928
929static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300930path_converter(PyObject *o, void *p)
931{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700932 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800933 PyObject *bytes = NULL;
934 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700935 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300936 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700937#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800938 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700939 const wchar_t *wide;
940#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941
942#define FORMAT_EXCEPTION(exc, fmt) \
943 PyErr_Format(exc, "%s%s" fmt, \
944 path->function_name ? path->function_name : "", \
945 path->function_name ? ": " : "", \
946 path->argument_name ? path->argument_name : "path")
947
948 /* Py_CLEANUP_SUPPORTED support */
949 if (o == NULL) {
950 path_cleanup(path);
951 return 1;
952 }
953
Brett Cannon3f9183b2016-08-26 14:44:48 -0700954 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800955 path->object = path->cleanup = NULL;
956 /* path->object owns a reference to the original object */
957 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300959 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700961#ifdef MS_WINDOWS
962 path->narrow = FALSE;
963#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700965#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800967 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 }
969
Brett Cannon3f9183b2016-08-26 14:44:48 -0700970 /* Only call this here so that we don't treat the return value of
971 os.fspath() as an fd or buffer. */
972 is_index = path->allow_fd && PyIndex_Check(o);
973 is_buffer = PyObject_CheckBuffer(o);
974 is_bytes = PyBytes_Check(o);
975 is_unicode = PyUnicode_Check(o);
976
977 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
978 /* Inline PyOS_FSPath() for better error messages. */
979 _Py_IDENTIFIER(__fspath__);
980 PyObject *func = NULL;
981
982 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
983 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800984 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700985 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800986 /* still owns a reference to the original object */
987 Py_DECREF(o);
988 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700989 Py_DECREF(func);
990 if (NULL == o) {
991 goto error_exit;
992 }
993 else if (PyUnicode_Check(o)) {
994 is_unicode = 1;
995 }
996 else if (PyBytes_Check(o)) {
997 is_bytes = 1;
998 }
999 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001000 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001001 }
1002 }
1003
1004 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001006 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001007 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001008 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001009 }
Victor Stinner59799a82013-11-13 14:17:30 +01001010 if (length > 32767) {
1011 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001012 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001013 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001014 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001015 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001016 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001017 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001018
1019 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001022 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001023#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001024 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001025 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001026 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027#endif
1028 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001029 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001030 bytes = o;
1031 Py_INCREF(bytes);
1032 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001033 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001034 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001035 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001036 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1037 "%s%s%s should be %s, not %.200s",
1038 path->function_name ? path->function_name : "",
1039 path->function_name ? ": " : "",
1040 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001041 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1042 "integer or None" :
1043 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1044 path->nullable ? "string, bytes, os.PathLike or None" :
1045 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001046 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001047 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001049 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 }
1053 }
Steve Dowercc16be82016-09-08 10:35:16 -07001054 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001055 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001056 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001057 }
1058 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001059#ifdef MS_WINDOWS
1060 path->narrow = FALSE;
1061#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001062 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001063#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001064 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001065 }
1066 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001067 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001068 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1069 path->function_name ? path->function_name : "",
1070 path->function_name ? ": " : "",
1071 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001072 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1073 "integer or None" :
1074 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1075 path->nullable ? "string, bytes, os.PathLike or None" :
1076 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001077 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001078 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 }
1080
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001082 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001083 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001084 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001085 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086 }
1087
Steve Dowercc16be82016-09-08 10:35:16 -07001088#ifdef MS_WINDOWS
1089 wo = PyUnicode_DecodeFSDefaultAndSize(
1090 narrow,
1091 length
1092 );
1093 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001094 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001095 }
1096
Xiang Zhang04316c42017-01-08 23:26:57 +08001097 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001098 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001100 }
1101 if (length > 32767) {
1102 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001104 }
1105 if (wcslen(wide) != length) {
1106 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001108 }
1109 path->wide = wide;
1110 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001111 path->cleanup = wo;
1112 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001113#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001114 path->wide = NULL;
1115 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001116 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001117 /* Still a reference owned by path->object, don't have to
1118 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001119 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001120 }
1121 else {
1122 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001123 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001124#endif
1125 path->fd = -1;
1126
1127 success_exit:
1128 path->length = length;
1129 path->object = o;
1130 return Py_CLEANUP_SUPPORTED;
1131
1132 error_exit:
1133 Py_XDECREF(o);
1134 Py_XDECREF(bytes);
1135#ifdef MS_WINDOWS
1136 Py_XDECREF(wo);
1137#endif
1138 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001139}
1140
1141static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001142argument_unavailable_error(const char *function_name, const char *argument_name)
1143{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001144 PyErr_Format(PyExc_NotImplementedError,
1145 "%s%s%s unavailable on this platform",
1146 (function_name != NULL) ? function_name : "",
1147 (function_name != NULL) ? ": ": "",
1148 argument_name);
1149}
1150
1151static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001152dir_fd_unavailable(PyObject *o, void *p)
1153{
1154 int dir_fd;
1155 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001156 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001157 if (dir_fd != DEFAULT_DIR_FD) {
1158 argument_unavailable_error(NULL, "dir_fd");
1159 return 0;
1160 }
1161 *(int *)p = dir_fd;
1162 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163}
1164
1165static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001166fd_specified(const char *function_name, int fd)
1167{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001168 if (fd == -1)
1169 return 0;
1170
1171 argument_unavailable_error(function_name, "fd");
1172 return 1;
1173}
1174
1175static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001176follow_symlinks_specified(const char *function_name, int follow_symlinks)
1177{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001178 if (follow_symlinks)
1179 return 0;
1180
1181 argument_unavailable_error(function_name, "follow_symlinks");
1182 return 1;
1183}
1184
1185static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001186path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1187{
Steve Dowercc16be82016-09-08 10:35:16 -07001188 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1189#ifndef MS_WINDOWS
1190 && !path->narrow
1191#endif
1192 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001193 PyErr_Format(PyExc_ValueError,
1194 "%s: can't specify dir_fd without matching path",
1195 function_name);
1196 return 1;
1197 }
1198 return 0;
1199}
1200
1201static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001202dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1203{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001204 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1205 PyErr_Format(PyExc_ValueError,
1206 "%s: can't specify both dir_fd and fd",
1207 function_name);
1208 return 1;
1209 }
1210 return 0;
1211}
1212
1213static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001214fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1215 int follow_symlinks)
1216{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001217 if ((fd > 0) && (!follow_symlinks)) {
1218 PyErr_Format(PyExc_ValueError,
1219 "%s: cannot use fd and follow_symlinks together",
1220 function_name);
1221 return 1;
1222 }
1223 return 0;
1224}
1225
1226static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001227dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1228 int follow_symlinks)
1229{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001230 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1231 PyErr_Format(PyExc_ValueError,
1232 "%s: cannot use dir_fd and follow_symlinks together",
1233 function_name);
1234 return 1;
1235 }
1236 return 0;
1237}
1238
Larry Hastings2f936352014-08-05 14:04:04 +10001239#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001240 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001241#else
Larry Hastings2f936352014-08-05 14:04:04 +10001242 typedef off_t Py_off_t;
1243#endif
1244
1245static int
1246Py_off_t_converter(PyObject *arg, void *addr)
1247{
1248#ifdef HAVE_LARGEFILE_SUPPORT
1249 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1250#else
1251 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001252#endif
1253 if (PyErr_Occurred())
1254 return 0;
1255 return 1;
1256}
Larry Hastings2f936352014-08-05 14:04:04 +10001257
1258static PyObject *
1259PyLong_FromPy_off_t(Py_off_t offset)
1260{
1261#ifdef HAVE_LARGEFILE_SUPPORT
1262 return PyLong_FromLongLong(offset);
1263#else
1264 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001265#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001266}
1267
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001268#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001269
1270static int
Brian Curtind25aef52011-06-13 15:16:04 -05001271win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001272{
Martin Panter70214ad2016-08-04 02:38:59 +00001273 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1274 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001275 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276
1277 if (0 == DeviceIoControl(
1278 reparse_point_handle,
1279 FSCTL_GET_REPARSE_POINT,
1280 NULL, 0, /* in buffer */
1281 target_buffer, sizeof(target_buffer),
1282 &n_bytes_returned,
1283 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001284 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001285
1286 if (reparse_tag)
1287 *reparse_tag = rdb->ReparseTag;
1288
Brian Curtind25aef52011-06-13 15:16:04 -05001289 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001290}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001291
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001292#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001293
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001294/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001295#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001296/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001297** environ directly, we must obtain it with _NSGetEnviron(). See also
1298** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001299*/
1300#include <crt_externs.h>
1301static char **environ;
1302#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001304#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305
Barry Warsaw53699e91996-12-10 23:23:01 +00001306static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001307convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308{
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001310#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001314#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001315
Victor Stinner8c62be82010-05-06 00:08:46 +00001316 d = PyDict_New();
1317 if (d == NULL)
1318 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001319#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001320 if (environ == NULL)
1321 environ = *_NSGetEnviron();
1322#endif
1323#ifdef MS_WINDOWS
1324 /* _wenviron must be initialized in this way if the program is started
1325 through main() instead of wmain(). */
1326 _wgetenv(L"");
1327 if (_wenviron == NULL)
1328 return d;
1329 /* This part ignores errors */
1330 for (e = _wenviron; *e != NULL; e++) {
1331 PyObject *k;
1332 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001333 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001334 if (p == NULL)
1335 continue;
1336 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1337 if (k == NULL) {
1338 PyErr_Clear();
1339 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001340 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001341 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1342 if (v == NULL) {
1343 PyErr_Clear();
1344 Py_DECREF(k);
1345 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001346 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001347 if (PyDict_GetItem(d, k) == NULL) {
1348 if (PyDict_SetItem(d, k, v) != 0)
1349 PyErr_Clear();
1350 }
1351 Py_DECREF(k);
1352 Py_DECREF(v);
1353 }
1354#else
1355 if (environ == NULL)
1356 return d;
1357 /* This part ignores errors */
1358 for (e = environ; *e != NULL; e++) {
1359 PyObject *k;
1360 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001361 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 if (p == NULL)
1363 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001364 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001365 if (k == NULL) {
1366 PyErr_Clear();
1367 continue;
1368 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001369 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001370 if (v == NULL) {
1371 PyErr_Clear();
1372 Py_DECREF(k);
1373 continue;
1374 }
1375 if (PyDict_GetItem(d, k) == NULL) {
1376 if (PyDict_SetItem(d, k, v) != 0)
1377 PyErr_Clear();
1378 }
1379 Py_DECREF(k);
1380 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001381 }
1382#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001384}
1385
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001386/* Set a POSIX-specific error from errno, and return NULL */
1387
Barry Warsawd58d7641998-07-23 16:14:40 +00001388static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001389posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001390{
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392}
Mark Hammondef8b6542001-05-13 08:04:26 +00001393
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001394#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001395static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001396win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001397{
Victor Stinner8c62be82010-05-06 00:08:46 +00001398 /* XXX We should pass the function name along in the future.
1399 (winreg.c also wants to pass the function name.)
1400 This would however require an additional param to the
1401 Windows error object, which is non-trivial.
1402 */
1403 errno = GetLastError();
1404 if (filename)
1405 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1406 else
1407 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001408}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001409
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001410static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001411win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001412{
1413 /* XXX - see win32_error for comments on 'function' */
1414 errno = GetLastError();
1415 if (filename)
1416 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001417 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001418 errno,
1419 filename);
1420 else
1421 return PyErr_SetFromWindowsErr(errno);
1422}
1423
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001424#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001425
Larry Hastings9cf065c2012-06-22 16:30:09 -07001426static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001427path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001428{
1429#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001430 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1431 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001433 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001434#endif
1435}
1436
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001437static PyObject *
1438path_object_error2(PyObject *path, PyObject *path2)
1439{
1440#ifdef MS_WINDOWS
1441 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1442 PyExc_OSError, 0, path, path2);
1443#else
1444 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1445#endif
1446}
1447
1448static PyObject *
1449path_error(path_t *path)
1450{
1451 return path_object_error(path->object);
1452}
Larry Hastings31826802013-10-19 00:09:25 -07001453
Larry Hastingsb0827312014-02-09 22:05:19 -08001454static PyObject *
1455path_error2(path_t *path, path_t *path2)
1456{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001457 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001458}
1459
1460
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461/* POSIX generic methods */
1462
Larry Hastings2f936352014-08-05 14:04:04 +10001463static int
1464fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001465{
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001467 int *pointer = (int *)p;
1468 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001469 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001470 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001471 *pointer = fd;
1472 return 1;
1473}
1474
1475static PyObject *
1476posix_fildes_fd(int fd, int (*func)(int))
1477{
1478 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001479 int async_err = 0;
1480
1481 do {
1482 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001483 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001484 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001485 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001486 Py_END_ALLOW_THREADS
1487 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1488 if (res != 0)
1489 return (!async_err) ? posix_error() : NULL;
1490 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001491}
Guido van Rossum21142a01999-01-08 21:05:37 +00001492
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001493
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001494#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495/* This is a reimplementation of the C library's chdir function,
1496 but one that produces Win32 errors instead of DOS error codes.
1497 chdir is essentially a wrapper around SetCurrentDirectory; however,
1498 it also needs to set "magic" environment variables indicating
1499 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001500static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001501win32_wchdir(LPCWSTR path)
1502{
Victor Stinnered537822015-12-13 21:40:26 +01001503 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001504 int result;
1505 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001506
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 if(!SetCurrentDirectoryW(path))
1508 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001509 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001510 if (!result)
1511 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001512 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001513 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 if (!new_path) {
1515 SetLastError(ERROR_OUTOFMEMORY);
1516 return FALSE;
1517 }
1518 result = GetCurrentDirectoryW(result, new_path);
1519 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001520 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 return FALSE;
1522 }
1523 }
1524 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1525 wcsncmp(new_path, L"//", 2) == 0)
1526 /* UNC path, nothing to do. */
1527 return TRUE;
1528 env[1] = new_path[0];
1529 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001530 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001531 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001532 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533}
1534#endif
1535
Martin v. Löwis14694662006-02-03 12:54:16 +00001536#ifdef MS_WINDOWS
1537/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1538 - time stamps are restricted to second resolution
1539 - file modification times suffer from forth-and-back conversions between
1540 UTC and local time
1541 Therefore, we implement our own stat, based on the Win32 API directly.
1542*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001543#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001544#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001545
Victor Stinner6036e442015-03-08 01:58:04 +01001546static void
Steve Dowercc16be82016-09-08 10:35:16 -07001547find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1548 BY_HANDLE_FILE_INFORMATION *info,
1549 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001550{
1551 memset(info, 0, sizeof(*info));
1552 info->dwFileAttributes = pFileData->dwFileAttributes;
1553 info->ftCreationTime = pFileData->ftCreationTime;
1554 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1555 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1556 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1557 info->nFileSizeLow = pFileData->nFileSizeLow;
1558/* info->nNumberOfLinks = 1; */
1559 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1560 *reparse_tag = pFileData->dwReserved0;
1561 else
1562 *reparse_tag = 0;
1563}
1564
Guido van Rossumd8faa362007-04-27 19:54:29 +00001565static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001566attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001567{
Victor Stinner8c62be82010-05-06 00:08:46 +00001568 HANDLE hFindFile;
1569 WIN32_FIND_DATAW FileData;
1570 hFindFile = FindFirstFileW(pszFile, &FileData);
1571 if (hFindFile == INVALID_HANDLE_VALUE)
1572 return FALSE;
1573 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001574 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001576}
1577
Brian Curtind25aef52011-06-13 15:16:04 -05001578static BOOL
1579get_target_path(HANDLE hdl, wchar_t **target_path)
1580{
1581 int buf_size, result_length;
1582 wchar_t *buf;
1583
1584 /* We have a good handle to the target, use it to determine
1585 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001586 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1587 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001588 if(!buf_size)
1589 return FALSE;
1590
Victor Stinnerc36674a2016-03-16 14:30:16 +01001591 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001592 if (!buf) {
1593 SetLastError(ERROR_OUTOFMEMORY);
1594 return FALSE;
1595 }
1596
Steve Dower2ea51c92015-03-20 21:49:12 -07001597 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001598 buf, buf_size, VOLUME_NAME_DOS);
1599
1600 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001601 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001602 return FALSE;
1603 }
1604
1605 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001606 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001607 return FALSE;
1608 }
1609
1610 buf[result_length] = 0;
1611
1612 *target_path = buf;
1613 return TRUE;
1614}
1615
1616static int
Steve Dowercc16be82016-09-08 10:35:16 -07001617win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001618 BOOL traverse)
1619{
Victor Stinner26de69d2011-06-17 15:15:38 +02001620 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001621 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001624 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001625 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626
Steve Dowercc16be82016-09-08 10:35:16 -07001627 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001628 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001629 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001630 0, /* share mode */
1631 NULL, /* security attributes */
1632 OPEN_EXISTING,
1633 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001634 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1635 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001636 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001637 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1638 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 NULL);
1640
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001641 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001642 /* Either the target doesn't exist, or we don't have access to
1643 get a handle to it. If the former, we need to return an error.
1644 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001645 DWORD lastError = GetLastError();
1646 if (lastError != ERROR_ACCESS_DENIED &&
1647 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001648 return -1;
1649 /* Could not get attributes on open file. Fall back to
1650 reading the directory. */
1651 if (!attributes_from_dir(path, &info, &reparse_tag))
1652 /* Very strange. This should not fail now */
1653 return -1;
1654 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1655 if (traverse) {
1656 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001657 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 } else {
1662 if (!GetFileInformationByHandle(hFile, &info)) {
1663 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001664 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 }
1666 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001667 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1668 return -1;
1669
1670 /* Close the outer open file handle now that we're about to
1671 reopen it with different flags. */
1672 if (!CloseHandle(hFile))
1673 return -1;
1674
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001676 /* In order to call GetFinalPathNameByHandle we need to open
1677 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001678 hFile2 = CreateFileW(
1679 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1680 NULL, OPEN_EXISTING,
1681 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1682 NULL);
1683 if (hFile2 == INVALID_HANDLE_VALUE)
1684 return -1;
1685
1686 if (!get_target_path(hFile2, &target_path))
1687 return -1;
1688
Steve Dowercc16be82016-09-08 10:35:16 -07001689 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001690 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001691 return code;
1692 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001693 } else
1694 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001695 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001696 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697
1698 /* Set S_IEXEC if it is an .exe, .bat, ... */
1699 dot = wcsrchr(path, '.');
1700 if (dot) {
1701 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1702 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1703 result->st_mode |= 0111;
1704 }
1705 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706}
1707
1708static int
Steve Dowercc16be82016-09-08 10:35:16 -07001709win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 /* Protocol violation: we explicitly clear errno, instead of
1712 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001713 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 errno = 0;
1715 return code;
1716}
Brian Curtind25aef52011-06-13 15:16:04 -05001717/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001718
1719 In Posix, stat automatically traverses symlinks and returns the stat
1720 structure for the target. In Windows, the equivalent GetFileAttributes by
1721 default does not traverse symlinks and instead returns attributes for
1722 the symlink.
1723
1724 Therefore, win32_lstat will get the attributes traditionally, and
1725 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001726 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001727
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001728static int
Steve Dowercc16be82016-09-08 10:35:16 -07001729win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001730{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001731 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001732}
1733
Victor Stinner8c62be82010-05-06 00:08:46 +00001734static int
Steve Dowercc16be82016-09-08 10:35:16 -07001735win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001736{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001737 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001738}
1739
Martin v. Löwis14694662006-02-03 12:54:16 +00001740#endif /* MS_WINDOWS */
1741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001742PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001743"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001744This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001745 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001746or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1747\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001748Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1749or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001751See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001752
1753static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 {"st_mode", "protection bits"},
1755 {"st_ino", "inode"},
1756 {"st_dev", "device"},
1757 {"st_nlink", "number of hard links"},
1758 {"st_uid", "user ID of owner"},
1759 {"st_gid", "group ID of owner"},
1760 {"st_size", "total size, in bytes"},
1761 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1762 {NULL, "integer time of last access"},
1763 {NULL, "integer time of last modification"},
1764 {NULL, "integer time of last change"},
1765 {"st_atime", "time of last access"},
1766 {"st_mtime", "time of last modification"},
1767 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001768 {"st_atime_ns", "time of last access in nanoseconds"},
1769 {"st_mtime_ns", "time of last modification in nanoseconds"},
1770 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001771#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001772 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001773#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001774#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001775 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001776#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001777#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001778 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001779#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001780#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001782#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001783#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001785#endif
1786#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001788#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001789#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1790 {"st_file_attributes", "Windows file attribute bits"},
1791#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001793};
1794
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001795#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001796#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001798#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001799#endif
1800
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001801#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001802#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1803#else
1804#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1805#endif
1806
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001807#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001808#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1809#else
1810#define ST_RDEV_IDX ST_BLOCKS_IDX
1811#endif
1812
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001813#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1814#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1815#else
1816#define ST_FLAGS_IDX ST_RDEV_IDX
1817#endif
1818
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001819#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001820#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001821#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001822#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001823#endif
1824
1825#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1826#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1827#else
1828#define ST_BIRTHTIME_IDX ST_GEN_IDX
1829#endif
1830
Zachary Ware63f277b2014-06-19 09:46:37 -05001831#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1832#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1833#else
1834#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1835#endif
1836
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 "stat_result", /* name */
1839 stat_result__doc__, /* doc */
1840 stat_result_fields,
1841 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001842};
1843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001844PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001845"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1846This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001847 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001848or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851
1852static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 {"f_bsize", },
1854 {"f_frsize", },
1855 {"f_blocks", },
1856 {"f_bfree", },
1857 {"f_bavail", },
1858 {"f_files", },
1859 {"f_ffree", },
1860 {"f_favail", },
1861 {"f_flag", },
1862 {"f_namemax",},
1863 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864};
1865
1866static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 "statvfs_result", /* name */
1868 statvfs_result__doc__, /* doc */
1869 statvfs_result_fields,
1870 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001871};
1872
Ross Lagerwall7807c352011-03-17 20:20:30 +02001873#if defined(HAVE_WAITID) && !defined(__APPLE__)
1874PyDoc_STRVAR(waitid_result__doc__,
1875"waitid_result: Result from waitid.\n\n\
1876This object may be accessed either as a tuple of\n\
1877 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1878or via the attributes si_pid, si_uid, and so on.\n\
1879\n\
1880See os.waitid for more information.");
1881
1882static PyStructSequence_Field waitid_result_fields[] = {
1883 {"si_pid", },
1884 {"si_uid", },
1885 {"si_signo", },
1886 {"si_status", },
1887 {"si_code", },
1888 {0}
1889};
1890
1891static PyStructSequence_Desc waitid_result_desc = {
1892 "waitid_result", /* name */
1893 waitid_result__doc__, /* doc */
1894 waitid_result_fields,
1895 5
1896};
1897static PyTypeObject WaitidResultType;
1898#endif
1899
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001900static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001901static PyTypeObject StatResultType;
1902static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001903#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001904static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001905#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001906static newfunc structseq_new;
1907
1908static PyObject *
1909statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1910{
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 PyStructSequence *result;
1912 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001913
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 result = (PyStructSequence*)structseq_new(type, args, kwds);
1915 if (!result)
1916 return NULL;
1917 /* If we have been initialized from a tuple,
1918 st_?time might be set to None. Initialize it
1919 from the int slots. */
1920 for (i = 7; i <= 9; i++) {
1921 if (result->ob_item[i+3] == Py_None) {
1922 Py_DECREF(Py_None);
1923 Py_INCREF(result->ob_item[i]);
1924 result->ob_item[i+3] = result->ob_item[i];
1925 }
1926 }
1927 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001928}
1929
1930
Larry Hastings6fe20b32012-04-19 15:07:49 -07001931static PyObject *billion = NULL;
1932
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001933static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001934fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001935{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001936 PyObject *s = _PyLong_FromTime_t(sec);
1937 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1938 PyObject *s_in_ns = NULL;
1939 PyObject *ns_total = NULL;
1940 PyObject *float_s = NULL;
1941
1942 if (!(s && ns_fractional))
1943 goto exit;
1944
1945 s_in_ns = PyNumber_Multiply(s, billion);
1946 if (!s_in_ns)
1947 goto exit;
1948
1949 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1950 if (!ns_total)
1951 goto exit;
1952
Victor Stinner01b5aab2017-10-24 02:02:00 -07001953 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1954 if (!float_s) {
1955 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001956 }
1957
1958 PyStructSequence_SET_ITEM(v, index, s);
1959 PyStructSequence_SET_ITEM(v, index+3, float_s);
1960 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1961 s = NULL;
1962 float_s = NULL;
1963 ns_total = NULL;
1964exit:
1965 Py_XDECREF(s);
1966 Py_XDECREF(ns_fractional);
1967 Py_XDECREF(s_in_ns);
1968 Py_XDECREF(ns_total);
1969 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001970}
1971
Tim Peters5aa91602002-01-30 05:46:57 +00001972/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001973 (used by posix_stat() and posix_fstat()) */
1974static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001975_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001976{
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 unsigned long ansec, mnsec, cnsec;
1978 PyObject *v = PyStructSequence_New(&StatResultType);
1979 if (v == NULL)
1980 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001981
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01001983 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02001984 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001985#ifdef MS_WINDOWS
1986 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001987#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001988 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001989#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001991#if defined(MS_WINDOWS)
1992 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1993 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1994#else
1995 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1996 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1997#endif
xdegaye50e86032017-05-22 11:15:08 +02001998 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
1999 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002000
Martin v. Löwis14694662006-02-03 12:54:16 +00002001#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 ansec = st->st_atim.tv_nsec;
2003 mnsec = st->st_mtim.tv_nsec;
2004 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002005#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 ansec = st->st_atimespec.tv_nsec;
2007 mnsec = st->st_mtimespec.tv_nsec;
2008 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002009#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 ansec = st->st_atime_nsec;
2011 mnsec = st->st_mtime_nsec;
2012 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002013#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002015#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002016 fill_time(v, 7, st->st_atime, ansec);
2017 fill_time(v, 8, st->st_mtime, mnsec);
2018 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002019
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002020#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2022 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002024#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002025 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2026 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002028#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2030 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002031#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002032#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2034 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002035#endif
2036#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002038 PyObject *val;
2039 unsigned long bsec,bnsec;
2040 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002041#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002042 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002043#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002044 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002045#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002046 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002047 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2048 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002050#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002051#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2053 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002054#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002055#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2056 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2057 PyLong_FromUnsignedLong(st->st_file_attributes));
2058#endif
Fred Drake699f3522000-06-29 21:12:41 +00002059
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 if (PyErr_Occurred()) {
2061 Py_DECREF(v);
2062 return NULL;
2063 }
Fred Drake699f3522000-06-29 21:12:41 +00002064
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002066}
2067
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068/* POSIX methods */
2069
Guido van Rossum94f6f721999-01-06 18:42:14 +00002070
2071static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002072posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002073 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002074{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075 STRUCT_STAT st;
2076 int result;
2077
2078#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2079 if (follow_symlinks_specified(function_name, follow_symlinks))
2080 return NULL;
2081#endif
2082
2083 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2084 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2085 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2086 return NULL;
2087
2088 Py_BEGIN_ALLOW_THREADS
2089 if (path->fd != -1)
2090 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002091#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002092 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002093 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002094 else
Steve Dowercc16be82016-09-08 10:35:16 -07002095 result = win32_lstat(path->wide, &st);
2096#else
2097 else
2098#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002099 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2100 result = LSTAT(path->narrow, &st);
2101 else
Steve Dowercc16be82016-09-08 10:35:16 -07002102#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002103#ifdef HAVE_FSTATAT
2104 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2105 result = fstatat(dir_fd, path->narrow, &st,
2106 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2107 else
Steve Dowercc16be82016-09-08 10:35:16 -07002108#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002109 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002110#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002111 Py_END_ALLOW_THREADS
2112
Victor Stinner292c8352012-10-30 02:17:38 +01002113 if (result != 0) {
2114 return path_error(path);
2115 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002116
2117 return _pystat_fromstructstat(&st);
2118}
2119
Larry Hastings2f936352014-08-05 14:04:04 +10002120/*[python input]
2121
2122for s in """
2123
2124FACCESSAT
2125FCHMODAT
2126FCHOWNAT
2127FSTATAT
2128LINKAT
2129MKDIRAT
2130MKFIFOAT
2131MKNODAT
2132OPENAT
2133READLINKAT
2134SYMLINKAT
2135UNLINKAT
2136
2137""".strip().split():
2138 s = s.strip()
2139 print("""
2140#ifdef HAVE_{s}
2141 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002142#else
Larry Hastings2f936352014-08-05 14:04:04 +10002143 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002144#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002145""".rstrip().format(s=s))
2146
2147for s in """
2148
2149FCHDIR
2150FCHMOD
2151FCHOWN
2152FDOPENDIR
2153FEXECVE
2154FPATHCONF
2155FSTATVFS
2156FTRUNCATE
2157
2158""".strip().split():
2159 s = s.strip()
2160 print("""
2161#ifdef HAVE_{s}
2162 #define PATH_HAVE_{s} 1
2163#else
2164 #define PATH_HAVE_{s} 0
2165#endif
2166
2167""".rstrip().format(s=s))
2168[python start generated code]*/
2169
2170#ifdef HAVE_FACCESSAT
2171 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2172#else
2173 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2174#endif
2175
2176#ifdef HAVE_FCHMODAT
2177 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2178#else
2179 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2180#endif
2181
2182#ifdef HAVE_FCHOWNAT
2183 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2184#else
2185 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2186#endif
2187
2188#ifdef HAVE_FSTATAT
2189 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2190#else
2191 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2192#endif
2193
2194#ifdef HAVE_LINKAT
2195 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_MKDIRAT
2201 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_MKFIFOAT
2207 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2208#else
2209 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2210#endif
2211
2212#ifdef HAVE_MKNODAT
2213 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_OPENAT
2219 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_READLINKAT
2225 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_SYMLINKAT
2231 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_UNLINKAT
2237 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_FCHDIR
2243 #define PATH_HAVE_FCHDIR 1
2244#else
2245 #define PATH_HAVE_FCHDIR 0
2246#endif
2247
2248#ifdef HAVE_FCHMOD
2249 #define PATH_HAVE_FCHMOD 1
2250#else
2251 #define PATH_HAVE_FCHMOD 0
2252#endif
2253
2254#ifdef HAVE_FCHOWN
2255 #define PATH_HAVE_FCHOWN 1
2256#else
2257 #define PATH_HAVE_FCHOWN 0
2258#endif
2259
2260#ifdef HAVE_FDOPENDIR
2261 #define PATH_HAVE_FDOPENDIR 1
2262#else
2263 #define PATH_HAVE_FDOPENDIR 0
2264#endif
2265
2266#ifdef HAVE_FEXECVE
2267 #define PATH_HAVE_FEXECVE 1
2268#else
2269 #define PATH_HAVE_FEXECVE 0
2270#endif
2271
2272#ifdef HAVE_FPATHCONF
2273 #define PATH_HAVE_FPATHCONF 1
2274#else
2275 #define PATH_HAVE_FPATHCONF 0
2276#endif
2277
2278#ifdef HAVE_FSTATVFS
2279 #define PATH_HAVE_FSTATVFS 1
2280#else
2281 #define PATH_HAVE_FSTATVFS 0
2282#endif
2283
2284#ifdef HAVE_FTRUNCATE
2285 #define PATH_HAVE_FTRUNCATE 1
2286#else
2287 #define PATH_HAVE_FTRUNCATE 0
2288#endif
2289/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002290
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002291#ifdef MS_WINDOWS
2292 #undef PATH_HAVE_FTRUNCATE
2293 #define PATH_HAVE_FTRUNCATE 1
2294#endif
Larry Hastings31826802013-10-19 00:09:25 -07002295
Larry Hastings61272b72014-01-07 12:41:53 -08002296/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002297
2298class path_t_converter(CConverter):
2299
2300 type = "path_t"
2301 impl_by_reference = True
2302 parse_by_reference = True
2303
2304 converter = 'path_converter'
2305
2306 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002307 # right now path_t doesn't support default values.
2308 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002309 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002310 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002311
Larry Hastings2f936352014-08-05 14:04:04 +10002312 if self.c_default not in (None, 'Py_None'):
2313 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002314
2315 self.nullable = nullable
2316 self.allow_fd = allow_fd
2317
Larry Hastings7726ac92014-01-31 22:03:12 -08002318 def pre_render(self):
2319 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002320 if isinstance(value, str):
2321 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002322 return str(int(bool(value)))
2323
2324 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002325 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002326 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002327 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002328 strify(self.nullable),
2329 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002330 )
2331
2332 def cleanup(self):
2333 return "path_cleanup(&" + self.name + ");\n"
2334
2335
2336class dir_fd_converter(CConverter):
2337 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002338
Larry Hastings2f936352014-08-05 14:04:04 +10002339 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002340 if self.default in (unspecified, None):
2341 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002342 if isinstance(requires, str):
2343 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2344 else:
2345 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002346
Larry Hastings2f936352014-08-05 14:04:04 +10002347class fildes_converter(CConverter):
2348 type = 'int'
2349 converter = 'fildes_converter'
2350
2351class uid_t_converter(CConverter):
2352 type = "uid_t"
2353 converter = '_Py_Uid_Converter'
2354
2355class gid_t_converter(CConverter):
2356 type = "gid_t"
2357 converter = '_Py_Gid_Converter'
2358
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002359class dev_t_converter(CConverter):
2360 type = 'dev_t'
2361 converter = '_Py_Dev_Converter'
2362
2363class dev_t_return_converter(unsigned_long_return_converter):
2364 type = 'dev_t'
2365 conversion_fn = '_PyLong_FromDev'
2366 unsigned_cast = '(dev_t)'
2367
Larry Hastings2f936352014-08-05 14:04:04 +10002368class FSConverter_converter(CConverter):
2369 type = 'PyObject *'
2370 converter = 'PyUnicode_FSConverter'
2371 def converter_init(self):
2372 if self.default is not unspecified:
2373 fail("FSConverter_converter does not support default values")
2374 self.c_default = 'NULL'
2375
2376 def cleanup(self):
2377 return "Py_XDECREF(" + self.name + ");\n"
2378
2379class pid_t_converter(CConverter):
2380 type = 'pid_t'
2381 format_unit = '" _Py_PARSE_PID "'
2382
2383class idtype_t_converter(int_converter):
2384 type = 'idtype_t'
2385
2386class id_t_converter(CConverter):
2387 type = 'id_t'
2388 format_unit = '" _Py_PARSE_PID "'
2389
Benjamin Petersonca470632016-09-06 13:47:26 -07002390class intptr_t_converter(CConverter):
2391 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002392 format_unit = '" _Py_PARSE_INTPTR "'
2393
2394class Py_off_t_converter(CConverter):
2395 type = 'Py_off_t'
2396 converter = 'Py_off_t_converter'
2397
2398class Py_off_t_return_converter(long_return_converter):
2399 type = 'Py_off_t'
2400 conversion_fn = 'PyLong_FromPy_off_t'
2401
2402class path_confname_converter(CConverter):
2403 type="int"
2404 converter="conv_path_confname"
2405
2406class confstr_confname_converter(path_confname_converter):
2407 converter='conv_confstr_confname'
2408
2409class sysconf_confname_converter(path_confname_converter):
2410 converter="conv_sysconf_confname"
2411
2412class sched_param_converter(CConverter):
2413 type = 'struct sched_param'
2414 converter = 'convert_sched_param'
2415 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002416
Larry Hastings61272b72014-01-07 12:41:53 -08002417[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002418/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002419
Larry Hastings61272b72014-01-07 12:41:53 -08002420/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002421
Larry Hastings2a727912014-01-16 11:32:01 -08002422os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002423
2424 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002425 Path to be examined; can be string, bytes, path-like object or
2426 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002427
2428 *
2429
Larry Hastings2f936352014-08-05 14:04:04 +10002430 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002431 If not None, it should be a file descriptor open to a directory,
2432 and path should be a relative string; path will then be relative to
2433 that directory.
2434
2435 follow_symlinks: bool = True
2436 If False, and the last element of the path is a symbolic link,
2437 stat will examine the symbolic link itself instead of the file
2438 the link points to.
2439
2440Perform a stat system call on the given path.
2441
2442dir_fd and follow_symlinks may not be implemented
2443 on your platform. If they are unavailable, using them will raise a
2444 NotImplementedError.
2445
2446It's an error to use dir_fd or follow_symlinks when specifying path as
2447 an open file descriptor.
2448
Larry Hastings61272b72014-01-07 12:41:53 -08002449[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002450
Larry Hastings31826802013-10-19 00:09:25 -07002451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002452os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002453/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002454{
2455 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2456}
2457
Larry Hastings2f936352014-08-05 14:04:04 +10002458
2459/*[clinic input]
2460os.lstat
2461
2462 path : path_t
2463
2464 *
2465
2466 dir_fd : dir_fd(requires='fstatat') = None
2467
2468Perform a stat system call on the given path, without following symbolic links.
2469
2470Like stat(), but do not follow symbolic links.
2471Equivalent to stat(path, follow_symlinks=False).
2472[clinic start generated code]*/
2473
Larry Hastings2f936352014-08-05 14:04:04 +10002474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002475os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2476/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002477{
2478 int follow_symlinks = 0;
2479 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2480}
Larry Hastings31826802013-10-19 00:09:25 -07002481
Larry Hastings2f936352014-08-05 14:04:04 +10002482
Larry Hastings61272b72014-01-07 12:41:53 -08002483/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002484os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002485
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002486 path: path_t
2487 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002488
2489 mode: int
2490 Operating-system mode bitfield. Can be F_OK to test existence,
2491 or the inclusive-OR of R_OK, W_OK, and X_OK.
2492
2493 *
2494
Larry Hastings2f936352014-08-05 14:04:04 +10002495 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002496 If not None, it should be a file descriptor open to a directory,
2497 and path should be relative; path will then be relative to that
2498 directory.
2499
2500 effective_ids: bool = False
2501 If True, access will use the effective uid/gid instead of
2502 the real uid/gid.
2503
2504 follow_symlinks: bool = True
2505 If False, and the last element of the path is a symbolic link,
2506 access will examine the symbolic link itself instead of the file
2507 the link points to.
2508
2509Use the real uid/gid to test for access to a path.
2510
2511{parameters}
2512dir_fd, effective_ids, and follow_symlinks may not be implemented
2513 on your platform. If they are unavailable, using them will raise a
2514 NotImplementedError.
2515
2516Note that most operations will use the effective uid/gid, therefore this
2517 routine can be used in a suid/sgid environment to test if the invoking user
2518 has the specified access to the path.
2519
Larry Hastings61272b72014-01-07 12:41:53 -08002520[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002521
Larry Hastings2f936352014-08-05 14:04:04 +10002522static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002523os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002524 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002525/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002526{
Larry Hastings2f936352014-08-05 14:04:04 +10002527 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002528
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002529#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002530 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002531#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002533#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002534
Larry Hastings9cf065c2012-06-22 16:30:09 -07002535#ifndef HAVE_FACCESSAT
2536 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002537 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002538
2539 if (effective_ids) {
2540 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002541 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542 }
2543#endif
2544
2545#ifdef MS_WINDOWS
2546 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002547 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002548 Py_END_ALLOW_THREADS
2549
2550 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002551 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002552 * * we didn't get a -1, and
2553 * * write access wasn't requested,
2554 * * or the file isn't read-only,
2555 * * or it's a directory.
2556 * (Directories cannot be read-only on Windows.)
2557 */
Larry Hastings2f936352014-08-05 14:04:04 +10002558 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002559 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002561 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562#else
2563
2564 Py_BEGIN_ALLOW_THREADS
2565#ifdef HAVE_FACCESSAT
2566 if ((dir_fd != DEFAULT_DIR_FD) ||
2567 effective_ids ||
2568 !follow_symlinks) {
2569 int flags = 0;
2570 if (!follow_symlinks)
2571 flags |= AT_SYMLINK_NOFOLLOW;
2572 if (effective_ids)
2573 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002574 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 }
2576 else
2577#endif
Larry Hastings31826802013-10-19 00:09:25 -07002578 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002579 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002580 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002581#endif
2582
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002584}
2585
Guido van Rossumd371ff11999-01-25 16:12:23 +00002586#ifndef F_OK
2587#define F_OK 0
2588#endif
2589#ifndef R_OK
2590#define R_OK 4
2591#endif
2592#ifndef W_OK
2593#define W_OK 2
2594#endif
2595#ifndef X_OK
2596#define X_OK 1
2597#endif
2598
Larry Hastings31826802013-10-19 00:09:25 -07002599
Guido van Rossumd371ff11999-01-25 16:12:23 +00002600#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002601/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002602os.ttyname -> DecodeFSDefault
2603
2604 fd: int
2605 Integer file descriptor handle.
2606
2607 /
2608
2609Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002610[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002611
Larry Hastings31826802013-10-19 00:09:25 -07002612static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002613os_ttyname_impl(PyObject *module, int fd)
2614/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002615{
2616 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002617
Larry Hastings31826802013-10-19 00:09:25 -07002618 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002619 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002620 posix_error();
2621 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002622}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002623#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002624
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002625#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002626/*[clinic input]
2627os.ctermid
2628
2629Return the name of the controlling terminal for this process.
2630[clinic start generated code]*/
2631
Larry Hastings2f936352014-08-05 14:04:04 +10002632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002633os_ctermid_impl(PyObject *module)
2634/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002635{
Victor Stinner8c62be82010-05-06 00:08:46 +00002636 char *ret;
2637 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002638
Greg Wardb48bc172000-03-01 21:51:56 +00002639#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002640 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002641#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002643#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002644 if (ret == NULL)
2645 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002646 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002647}
Larry Hastings2f936352014-08-05 14:04:04 +10002648#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002649
Larry Hastings2f936352014-08-05 14:04:04 +10002650
2651/*[clinic input]
2652os.chdir
2653
2654 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2655
2656Change the current working directory to the specified path.
2657
2658path may always be specified as a string.
2659On some platforms, path may also be specified as an open file descriptor.
2660 If this functionality is unavailable, using it raises an exception.
2661[clinic start generated code]*/
2662
Larry Hastings2f936352014-08-05 14:04:04 +10002663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002664os_chdir_impl(PyObject *module, path_t *path)
2665/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002666{
2667 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002668
2669 Py_BEGIN_ALLOW_THREADS
2670#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002671 /* on unix, success = 0, on windows, success = !0 */
2672 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002673#else
2674#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002675 if (path->fd != -1)
2676 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002677 else
2678#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002679 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002680#endif
2681 Py_END_ALLOW_THREADS
2682
2683 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002684 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002685 }
2686
Larry Hastings2f936352014-08-05 14:04:04 +10002687 Py_RETURN_NONE;
2688}
2689
2690
2691#ifdef HAVE_FCHDIR
2692/*[clinic input]
2693os.fchdir
2694
2695 fd: fildes
2696
2697Change to the directory of the given file descriptor.
2698
2699fd must be opened on a directory, not a file.
2700Equivalent to os.chdir(fd).
2701
2702[clinic start generated code]*/
2703
Fred Drake4d1e64b2002-04-15 19:40:07 +00002704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002705os_fchdir_impl(PyObject *module, int fd)
2706/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002707{
Larry Hastings2f936352014-08-05 14:04:04 +10002708 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002709}
2710#endif /* HAVE_FCHDIR */
2711
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002712
Larry Hastings2f936352014-08-05 14:04:04 +10002713/*[clinic input]
2714os.chmod
2715
2716 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2717 Path to be modified. May always be specified as a str or bytes.
2718 On some platforms, path may also be specified as an open file descriptor.
2719 If this functionality is unavailable, using it raises an exception.
2720
2721 mode: int
2722 Operating-system mode bitfield.
2723
2724 *
2725
2726 dir_fd : dir_fd(requires='fchmodat') = None
2727 If not None, it should be a file descriptor open to a directory,
2728 and path should be relative; path will then be relative to that
2729 directory.
2730
2731 follow_symlinks: bool = True
2732 If False, and the last element of the path is a symbolic link,
2733 chmod will modify the symbolic link itself instead of the file
2734 the link points to.
2735
2736Change the access permissions of a file.
2737
2738It is an error to use dir_fd or follow_symlinks when specifying path as
2739 an open file descriptor.
2740dir_fd and follow_symlinks may not be implemented on your platform.
2741 If they are unavailable, using them will raise a NotImplementedError.
2742
2743[clinic start generated code]*/
2744
Larry Hastings2f936352014-08-05 14:04:04 +10002745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002746os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002747 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002748/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002749{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002750 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002751
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002752#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002753 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002754#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002755
Larry Hastings9cf065c2012-06-22 16:30:09 -07002756#ifdef HAVE_FCHMODAT
2757 int fchmodat_nofollow_unsupported = 0;
2758#endif
2759
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2761 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002762 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763#endif
2764
2765#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002766 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002767 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002768 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002769 result = 0;
2770 else {
2771 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002772 attr &= ~FILE_ATTRIBUTE_READONLY;
2773 else
2774 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002775 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002776 }
2777 Py_END_ALLOW_THREADS
2778
2779 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002780 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 }
2782#else /* MS_WINDOWS */
2783 Py_BEGIN_ALLOW_THREADS
2784#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002785 if (path->fd != -1)
2786 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787 else
2788#endif
2789#ifdef HAVE_LCHMOD
2790 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002791 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792 else
2793#endif
2794#ifdef HAVE_FCHMODAT
2795 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2796 /*
2797 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2798 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002799 * and then says it isn't implemented yet.
2800 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801 *
2802 * Once it is supported, os.chmod will automatically
2803 * support dir_fd and follow_symlinks=False. (Hopefully.)
2804 * Until then, we need to be careful what exception we raise.
2805 */
Larry Hastings2f936352014-08-05 14:04:04 +10002806 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2808 /*
2809 * But wait! We can't throw the exception without allowing threads,
2810 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2811 */
2812 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002813 result &&
2814 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2815 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002816 }
2817 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002818#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002819 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820 Py_END_ALLOW_THREADS
2821
2822 if (result) {
2823#ifdef HAVE_FCHMODAT
2824 if (fchmodat_nofollow_unsupported) {
2825 if (dir_fd != DEFAULT_DIR_FD)
2826 dir_fd_and_follow_symlinks_invalid("chmod",
2827 dir_fd, follow_symlinks);
2828 else
2829 follow_symlinks_specified("chmod", follow_symlinks);
2830 }
2831 else
2832#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002833 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002834 }
2835#endif
2836
Larry Hastings2f936352014-08-05 14:04:04 +10002837 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002838}
2839
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840
Christian Heimes4e30a842007-11-30 22:12:06 +00002841#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002842/*[clinic input]
2843os.fchmod
2844
2845 fd: int
2846 mode: int
2847
2848Change the access permissions of the file given by file descriptor fd.
2849
2850Equivalent to os.chmod(fd, mode).
2851[clinic start generated code]*/
2852
Larry Hastings2f936352014-08-05 14:04:04 +10002853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002854os_fchmod_impl(PyObject *module, int fd, int mode)
2855/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002856{
2857 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002858 int async_err = 0;
2859
2860 do {
2861 Py_BEGIN_ALLOW_THREADS
2862 res = fchmod(fd, mode);
2863 Py_END_ALLOW_THREADS
2864 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2865 if (res != 0)
2866 return (!async_err) ? posix_error() : NULL;
2867
Victor Stinner8c62be82010-05-06 00:08:46 +00002868 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002869}
2870#endif /* HAVE_FCHMOD */
2871
Larry Hastings2f936352014-08-05 14:04:04 +10002872
Christian Heimes4e30a842007-11-30 22:12:06 +00002873#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002874/*[clinic input]
2875os.lchmod
2876
2877 path: path_t
2878 mode: int
2879
2880Change the access permissions of a file, without following symbolic links.
2881
2882If path is a symlink, this affects the link itself rather than the target.
2883Equivalent to chmod(path, mode, follow_symlinks=False)."
2884[clinic start generated code]*/
2885
Larry Hastings2f936352014-08-05 14:04:04 +10002886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002887os_lchmod_impl(PyObject *module, path_t *path, int mode)
2888/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002889{
Victor Stinner8c62be82010-05-06 00:08:46 +00002890 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002892 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002894 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002895 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002896 return NULL;
2897 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002898 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002899}
2900#endif /* HAVE_LCHMOD */
2901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002902
Thomas Wouterscf297e42007-02-23 15:07:44 +00002903#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002904/*[clinic input]
2905os.chflags
2906
2907 path: path_t
2908 flags: unsigned_long(bitwise=True)
2909 follow_symlinks: bool=True
2910
2911Set file flags.
2912
2913If follow_symlinks is False, and the last element of the path is a symbolic
2914 link, chflags will change flags on the symbolic link itself instead of the
2915 file the link points to.
2916follow_symlinks may not be implemented on your platform. If it is
2917unavailable, using it will raise a NotImplementedError.
2918
2919[clinic start generated code]*/
2920
Larry Hastings2f936352014-08-05 14:04:04 +10002921static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002922os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002923 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002924/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002925{
2926 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002927
2928#ifndef HAVE_LCHFLAGS
2929 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002930 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002931#endif
2932
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002934#ifdef HAVE_LCHFLAGS
2935 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002936 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002937 else
2938#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002939 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002940 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002941
Larry Hastings2f936352014-08-05 14:04:04 +10002942 if (result)
2943 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002944
Larry Hastings2f936352014-08-05 14:04:04 +10002945 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002946}
2947#endif /* HAVE_CHFLAGS */
2948
Larry Hastings2f936352014-08-05 14:04:04 +10002949
Thomas Wouterscf297e42007-02-23 15:07:44 +00002950#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002951/*[clinic input]
2952os.lchflags
2953
2954 path: path_t
2955 flags: unsigned_long(bitwise=True)
2956
2957Set file flags.
2958
2959This function will not follow symbolic links.
2960Equivalent to chflags(path, flags, follow_symlinks=False).
2961[clinic start generated code]*/
2962
Larry Hastings2f936352014-08-05 14:04:04 +10002963static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002964os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2965/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002966{
Victor Stinner8c62be82010-05-06 00:08:46 +00002967 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002969 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002971 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002972 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002973 }
Victor Stinner292c8352012-10-30 02:17:38 +01002974 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002975}
2976#endif /* HAVE_LCHFLAGS */
2977
Larry Hastings2f936352014-08-05 14:04:04 +10002978
Martin v. Löwis244edc82001-10-04 22:44:26 +00002979#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002980/*[clinic input]
2981os.chroot
2982 path: path_t
2983
2984Change root directory to path.
2985
2986[clinic start generated code]*/
2987
Larry Hastings2f936352014-08-05 14:04:04 +10002988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002989os_chroot_impl(PyObject *module, path_t *path)
2990/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002991{
2992 int res;
2993 Py_BEGIN_ALLOW_THREADS
2994 res = chroot(path->narrow);
2995 Py_END_ALLOW_THREADS
2996 if (res < 0)
2997 return path_error(path);
2998 Py_RETURN_NONE;
2999}
3000#endif /* HAVE_CHROOT */
3001
Martin v. Löwis244edc82001-10-04 22:44:26 +00003002
Guido van Rossum21142a01999-01-08 21:05:37 +00003003#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003004/*[clinic input]
3005os.fsync
3006
3007 fd: fildes
3008
3009Force write of fd to disk.
3010[clinic start generated code]*/
3011
Larry Hastings2f936352014-08-05 14:04:04 +10003012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003013os_fsync_impl(PyObject *module, int fd)
3014/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003015{
3016 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003017}
3018#endif /* HAVE_FSYNC */
3019
Larry Hastings2f936352014-08-05 14:04:04 +10003020
Ross Lagerwall7807c352011-03-17 20:20:30 +02003021#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003022/*[clinic input]
3023os.sync
3024
3025Force write of everything to disk.
3026[clinic start generated code]*/
3027
Larry Hastings2f936352014-08-05 14:04:04 +10003028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003029os_sync_impl(PyObject *module)
3030/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003031{
3032 Py_BEGIN_ALLOW_THREADS
3033 sync();
3034 Py_END_ALLOW_THREADS
3035 Py_RETURN_NONE;
3036}
Larry Hastings2f936352014-08-05 14:04:04 +10003037#endif /* HAVE_SYNC */
3038
Ross Lagerwall7807c352011-03-17 20:20:30 +02003039
Guido van Rossum21142a01999-01-08 21:05:37 +00003040#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003041#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003042extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3043#endif
3044
Larry Hastings2f936352014-08-05 14:04:04 +10003045/*[clinic input]
3046os.fdatasync
3047
3048 fd: fildes
3049
3050Force write of fd to disk without forcing update of metadata.
3051[clinic start generated code]*/
3052
Larry Hastings2f936352014-08-05 14:04:04 +10003053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003054os_fdatasync_impl(PyObject *module, int fd)
3055/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003056{
3057 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003058}
3059#endif /* HAVE_FDATASYNC */
3060
3061
Fredrik Lundh10723342000-07-10 16:38:09 +00003062#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003063/*[clinic input]
3064os.chown
3065
3066 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3067 Path to be examined; can be string, bytes, or open-file-descriptor int.
3068
3069 uid: uid_t
3070
3071 gid: gid_t
3072
3073 *
3074
3075 dir_fd : dir_fd(requires='fchownat') = None
3076 If not None, it should be a file descriptor open to a directory,
3077 and path should be relative; path will then be relative to that
3078 directory.
3079
3080 follow_symlinks: bool = True
3081 If False, and the last element of the path is a symbolic link,
3082 stat will examine the symbolic link itself instead of the file
3083 the link points to.
3084
3085Change the owner and group id of path to the numeric uid and gid.\
3086
3087path may always be specified as a string.
3088On some platforms, path may also be specified as an open file descriptor.
3089 If this functionality is unavailable, using it raises an exception.
3090If dir_fd is not None, it should be a file descriptor open to a directory,
3091 and path should be relative; path will then be relative to that directory.
3092If follow_symlinks is False, and the last element of the path is a symbolic
3093 link, chown will modify the symbolic link itself instead of the file the
3094 link points to.
3095It is an error to use dir_fd or follow_symlinks when specifying path as
3096 an open file descriptor.
3097dir_fd and follow_symlinks may not be implemented on your platform.
3098 If they are unavailable, using them will raise a NotImplementedError.
3099
3100[clinic start generated code]*/
3101
Larry Hastings2f936352014-08-05 14:04:04 +10003102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003103os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003104 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003105/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003106{
3107 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108
3109#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3110 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003111 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003112#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003113 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3114 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3115 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003116
3117#ifdef __APPLE__
3118 /*
3119 * This is for Mac OS X 10.3, which doesn't have lchown.
3120 * (But we still have an lchown symbol because of weak-linking.)
3121 * It doesn't have fchownat either. So there's no possibility
3122 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003123 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124 if ((!follow_symlinks) && (lchown == NULL)) {
3125 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003126 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003127 }
3128#endif
3129
Victor Stinner8c62be82010-05-06 00:08:46 +00003130 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003131#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003132 if (path->fd != -1)
3133 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003134 else
3135#endif
3136#ifdef HAVE_LCHOWN
3137 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003138 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003139 else
3140#endif
3141#ifdef HAVE_FCHOWNAT
3142 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003143 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003144 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3145 else
3146#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003147 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003148 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149
Larry Hastings2f936352014-08-05 14:04:04 +10003150 if (result)
3151 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152
Larry Hastings2f936352014-08-05 14:04:04 +10003153 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003154}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003155#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003156
Larry Hastings2f936352014-08-05 14:04:04 +10003157
Christian Heimes4e30a842007-11-30 22:12:06 +00003158#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003159/*[clinic input]
3160os.fchown
3161
3162 fd: int
3163 uid: uid_t
3164 gid: gid_t
3165
3166Change the owner and group id of the file specified by file descriptor.
3167
3168Equivalent to os.chown(fd, uid, gid).
3169
3170[clinic start generated code]*/
3171
Larry Hastings2f936352014-08-05 14:04:04 +10003172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003173os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3174/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003175{
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003177 int async_err = 0;
3178
3179 do {
3180 Py_BEGIN_ALLOW_THREADS
3181 res = fchown(fd, uid, gid);
3182 Py_END_ALLOW_THREADS
3183 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3184 if (res != 0)
3185 return (!async_err) ? posix_error() : NULL;
3186
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003188}
3189#endif /* HAVE_FCHOWN */
3190
Larry Hastings2f936352014-08-05 14:04:04 +10003191
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003192#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003193/*[clinic input]
3194os.lchown
3195
3196 path : path_t
3197 uid: uid_t
3198 gid: gid_t
3199
3200Change the owner and group id of path to the numeric uid and gid.
3201
3202This function will not follow symbolic links.
3203Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3204[clinic start generated code]*/
3205
Larry Hastings2f936352014-08-05 14:04:04 +10003206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003207os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3208/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003209{
Victor Stinner8c62be82010-05-06 00:08:46 +00003210 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003212 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003214 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003215 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003216 }
Larry Hastings2f936352014-08-05 14:04:04 +10003217 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003218}
3219#endif /* HAVE_LCHOWN */
3220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003221
Barry Warsaw53699e91996-12-10 23:23:01 +00003222static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003223posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003224{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003225 char *buf, *tmpbuf;
3226 char *cwd;
3227 const size_t chunk = 1024;
3228 size_t buflen = 0;
3229 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003230
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003231#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003233 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 wchar_t *wbuf2 = wbuf;
3235 PyObject *resobj;
3236 DWORD len;
3237 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003238 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 /* If the buffer is large enough, len does not include the
3240 terminating \0. If the buffer is too small, len includes
3241 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003242 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003243 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003244 if (wbuf2)
3245 len = GetCurrentDirectoryW(len, wbuf2);
3246 }
3247 Py_END_ALLOW_THREADS
3248 if (!wbuf2) {
3249 PyErr_NoMemory();
3250 return NULL;
3251 }
3252 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003253 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003254 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003255 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 }
3257 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003258 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003259 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 return resobj;
3261 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003262
3263 if (win32_warn_bytes_api())
3264 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003265#endif
3266
Victor Stinner4403d7d2015-04-25 00:16:10 +02003267 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003268 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003269 do {
3270 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003271#ifdef MS_WINDOWS
3272 if (buflen > INT_MAX) {
3273 PyErr_NoMemory();
3274 break;
3275 }
3276#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003277 tmpbuf = PyMem_RawRealloc(buf, buflen);
3278 if (tmpbuf == NULL)
3279 break;
3280
3281 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003282#ifdef MS_WINDOWS
3283 cwd = getcwd(buf, (int)buflen);
3284#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003285 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003286#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003287 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003289
3290 if (cwd == NULL) {
3291 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003293 }
3294
Victor Stinner8c62be82010-05-06 00:08:46 +00003295 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003296 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3297 else
3298 obj = PyUnicode_DecodeFSDefault(buf);
3299 PyMem_RawFree(buf);
3300
3301 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003302}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003303
Larry Hastings2f936352014-08-05 14:04:04 +10003304
3305/*[clinic input]
3306os.getcwd
3307
3308Return a unicode string representing the current working directory.
3309[clinic start generated code]*/
3310
Larry Hastings2f936352014-08-05 14:04:04 +10003311static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003312os_getcwd_impl(PyObject *module)
3313/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003314{
3315 return posix_getcwd(0);
3316}
3317
Larry Hastings2f936352014-08-05 14:04:04 +10003318
3319/*[clinic input]
3320os.getcwdb
3321
3322Return a bytes string representing the current working directory.
3323[clinic start generated code]*/
3324
Larry Hastings2f936352014-08-05 14:04:04 +10003325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003326os_getcwdb_impl(PyObject *module)
3327/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003328{
3329 return posix_getcwd(1);
3330}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003331
Larry Hastings2f936352014-08-05 14:04:04 +10003332
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3334#define HAVE_LINK 1
3335#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003336
Guido van Rossumb6775db1994-08-01 11:34:53 +00003337#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003338/*[clinic input]
3339
3340os.link
3341
3342 src : path_t
3343 dst : path_t
3344 *
3345 src_dir_fd : dir_fd = None
3346 dst_dir_fd : dir_fd = None
3347 follow_symlinks: bool = True
3348
3349Create a hard link to a file.
3350
3351If either src_dir_fd or dst_dir_fd is not None, it should be a file
3352 descriptor open to a directory, and the respective path string (src or dst)
3353 should be relative; the path will then be relative to that directory.
3354If follow_symlinks is False, and the last element of src is a symbolic
3355 link, link will create a link to the symbolic link itself instead of the
3356 file the link points to.
3357src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3358 platform. If they are unavailable, using them will raise a
3359 NotImplementedError.
3360[clinic start generated code]*/
3361
Larry Hastings2f936352014-08-05 14:04:04 +10003362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003363os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003364 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003365/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003366{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003367#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003368 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003369#else
3370 int result;
3371#endif
3372
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373#ifndef HAVE_LINKAT
3374 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3375 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003376 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377 }
3378#endif
3379
Steve Dowercc16be82016-09-08 10:35:16 -07003380#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003381 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382 PyErr_SetString(PyExc_NotImplementedError,
3383 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003384 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 }
Steve Dowercc16be82016-09-08 10:35:16 -07003386#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003387
Brian Curtin1b9df392010-11-24 20:24:31 +00003388#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003390 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003392
Larry Hastings2f936352014-08-05 14:04:04 +10003393 if (!result)
3394 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395#else
3396 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003397#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3399 (dst_dir_fd != DEFAULT_DIR_FD) ||
3400 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003401 result = linkat(src_dir_fd, src->narrow,
3402 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3404 else
Steve Dowercc16be82016-09-08 10:35:16 -07003405#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003406 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003408
Larry Hastings2f936352014-08-05 14:04:04 +10003409 if (result)
3410 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003411#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003412
Larry Hastings2f936352014-08-05 14:04:04 +10003413 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003414}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415#endif
3416
Brian Curtin1b9df392010-11-24 20:24:31 +00003417
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003418#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003419static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003420_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003421{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 PyObject *v;
3423 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3424 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003425 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003427 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429
Steve Dowercc16be82016-09-08 10:35:16 -07003430 WIN32_FIND_DATAW wFileData;
3431 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003432
Steve Dowercc16be82016-09-08 10:35:16 -07003433 if (!path->wide) { /* Default arg: "." */
3434 po_wchars = L".";
3435 len = 1;
3436 } else {
3437 po_wchars = path->wide;
3438 len = wcslen(path->wide);
3439 }
3440 /* The +5 is so we can append "\\*.*\0" */
3441 wnamebuf = PyMem_New(wchar_t, len + 5);
3442 if (!wnamebuf) {
3443 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 }
Steve Dowercc16be82016-09-08 10:35:16 -07003446 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003448 wchar_t wch = wnamebuf[len-1];
3449 if (wch != SEP && wch != ALTSEP && wch != L':')
3450 wnamebuf[len++] = SEP;
3451 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 }
Steve Dowercc16be82016-09-08 10:35:16 -07003453 if ((list = PyList_New(0)) == NULL) {
3454 goto exit;
3455 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003456 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003457 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003458 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 if (hFindFile == INVALID_HANDLE_VALUE) {
3460 int error = GetLastError();
3461 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462 goto exit;
3463 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003464 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003466 }
3467 do {
3468 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003469 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3470 wcscmp(wFileData.cFileName, L"..") != 0) {
3471 v = PyUnicode_FromWideChar(wFileData.cFileName,
3472 wcslen(wFileData.cFileName));
3473 if (path->narrow && v) {
3474 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3475 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477 Py_DECREF(list);
3478 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003479 break;
3480 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 Py_DECREF(list);
3484 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 break;
3486 }
3487 Py_DECREF(v);
3488 }
3489 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003490 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 Py_END_ALLOW_THREADS
3492 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3493 it got to the end of the directory. */
3494 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003496 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 }
3499 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003500
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501exit:
3502 if (hFindFile != INVALID_HANDLE_VALUE) {
3503 if (FindClose(hFindFile) == FALSE) {
3504 if (list != NULL) {
3505 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003506 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 }
3508 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003510 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003511
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003513} /* end of _listdir_windows_no_opendir */
3514
3515#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3516
3517static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003518_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003519{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003520 PyObject *v;
3521 DIR *dirp = NULL;
3522 struct dirent *ep;
3523 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003524#ifdef HAVE_FDOPENDIR
3525 int fd = -1;
3526#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003527
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003530 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003532 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003533 if (fd == -1)
3534 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535
Larry Hastingsfdaea062012-06-25 04:42:23 -07003536 return_str = 1;
3537
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 Py_BEGIN_ALLOW_THREADS
3539 dirp = fdopendir(fd);
3540 Py_END_ALLOW_THREADS
3541 }
3542 else
3543#endif
3544 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003545 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003546 if (path->narrow) {
3547 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003548 /* only return bytes if they specified a bytes-like object */
3549 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003550 }
3551 else {
3552 name = ".";
3553 return_str = 1;
3554 }
3555
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 Py_BEGIN_ALLOW_THREADS
3557 dirp = opendir(name);
3558 Py_END_ALLOW_THREADS
3559 }
3560
3561 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003562 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003563#ifdef HAVE_FDOPENDIR
3564 if (fd != -1) {
3565 Py_BEGIN_ALLOW_THREADS
3566 close(fd);
3567 Py_END_ALLOW_THREADS
3568 }
3569#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570 goto exit;
3571 }
3572 if ((list = PyList_New(0)) == NULL) {
3573 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 }
3575 for (;;) {
3576 errno = 0;
3577 Py_BEGIN_ALLOW_THREADS
3578 ep = readdir(dirp);
3579 Py_END_ALLOW_THREADS
3580 if (ep == NULL) {
3581 if (errno == 0) {
3582 break;
3583 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003585 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003586 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 }
3588 }
3589 if (ep->d_name[0] == '.' &&
3590 (NAMLEN(ep) == 1 ||
3591 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3592 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003593 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003594 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3595 else
3596 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 break;
3600 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 break;
3605 }
3606 Py_DECREF(v);
3607 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003608
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609exit:
3610 if (dirp != NULL) {
3611 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003612#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 if (fd > -1)
3614 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003615#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616 closedir(dirp);
3617 Py_END_ALLOW_THREADS
3618 }
3619
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003621} /* end of _posix_listdir */
3622#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003623
Larry Hastings2f936352014-08-05 14:04:04 +10003624
3625/*[clinic input]
3626os.listdir
3627
3628 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3629
3630Return a list containing the names of the files in the directory.
3631
3632path can be specified as either str or bytes. If path is bytes,
3633 the filenames returned will also be bytes; in all other circumstances
3634 the filenames returned will be str.
3635If path is None, uses the path='.'.
3636On some platforms, path may also be specified as an open file descriptor;\
3637 the file descriptor must refer to a directory.
3638 If this functionality is unavailable, using it raises NotImplementedError.
3639
3640The list is in arbitrary order. It does not include the special
3641entries '.' and '..' even if they are present in the directory.
3642
3643
3644[clinic start generated code]*/
3645
Larry Hastings2f936352014-08-05 14:04:04 +10003646static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003647os_listdir_impl(PyObject *module, path_t *path)
3648/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003649{
3650#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3651 return _listdir_windows_no_opendir(path, NULL);
3652#else
3653 return _posix_listdir(path, NULL);
3654#endif
3655}
3656
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003657#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003658/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003659/*[clinic input]
3660os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003661
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003662 path: path_t
3663 /
3664
3665[clinic start generated code]*/
3666
3667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003668os__getfullpathname_impl(PyObject *module, path_t *path)
3669/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003670{
Steve Dowercc16be82016-09-08 10:35:16 -07003671 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3672 wchar_t *wtemp;
3673 DWORD result;
3674 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003675
Steve Dowercc16be82016-09-08 10:35:16 -07003676 result = GetFullPathNameW(path->wide,
3677 Py_ARRAY_LENGTH(woutbuf),
3678 woutbuf, &wtemp);
3679 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3680 woutbufp = PyMem_New(wchar_t, result);
3681 if (!woutbufp)
3682 return PyErr_NoMemory();
3683 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 }
Steve Dowercc16be82016-09-08 10:35:16 -07003685 if (result) {
3686 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3687 if (path->narrow)
3688 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3689 } else
3690 v = win32_error_object("GetFullPathNameW", path->object);
3691 if (woutbufp != woutbuf)
3692 PyMem_Free(woutbufp);
3693 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003694}
Brian Curtind40e6f72010-07-08 21:39:08 +00003695
Brian Curtind25aef52011-06-13 15:16:04 -05003696
Larry Hastings2f936352014-08-05 14:04:04 +10003697/*[clinic input]
3698os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003699
Larry Hastings2f936352014-08-05 14:04:04 +10003700 path: unicode
3701 /
3702
3703A helper function for samepath on windows.
3704[clinic start generated code]*/
3705
Larry Hastings2f936352014-08-05 14:04:04 +10003706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003707os__getfinalpathname_impl(PyObject *module, PyObject *path)
3708/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003709{
3710 HANDLE hFile;
3711 int buf_size;
3712 wchar_t *target_path;
3713 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003714 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003715 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003716
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03003717 path_wchar = _PyUnicode_AsUnicode(path);
Larry Hastings2f936352014-08-05 14:04:04 +10003718 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003719 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003720
Brian Curtind40e6f72010-07-08 21:39:08 +00003721 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003722 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003723 0, /* desired access */
3724 0, /* share mode */
3725 NULL, /* security attributes */
3726 OPEN_EXISTING,
3727 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3728 FILE_FLAG_BACKUP_SEMANTICS,
3729 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003730
Victor Stinnereb5657a2011-09-30 01:44:27 +02003731 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003732 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003733
3734 /* We have a good handle to the target, use it to determine the
3735 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003736 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003737
3738 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003739 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003740
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003741 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003742 if(!target_path)
3743 return PyErr_NoMemory();
3744
Steve Dower2ea51c92015-03-20 21:49:12 -07003745 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3746 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003747 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003748 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003749
3750 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003751 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003752
3753 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003754 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003755 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003756 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003757}
Brian Curtin62857742010-09-06 17:07:27 +00003758
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003759/*[clinic input]
3760os._isdir
3761
3762 path: path_t
3763 /
3764
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003765Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003766[clinic start generated code]*/
3767
Brian Curtin9c669cc2011-06-08 18:17:18 -05003768static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003769os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003770/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003771{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003772 DWORD attributes;
3773
Steve Dowerb22a6772016-07-17 20:49:38 -07003774 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003775 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003776 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003777
Brian Curtin9c669cc2011-06-08 18:17:18 -05003778 if (attributes == INVALID_FILE_ATTRIBUTES)
3779 Py_RETURN_FALSE;
3780
Brian Curtin9c669cc2011-06-08 18:17:18 -05003781 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3782 Py_RETURN_TRUE;
3783 else
3784 Py_RETURN_FALSE;
3785}
Tim Golden6b528062013-08-01 12:44:00 +01003786
Tim Golden6b528062013-08-01 12:44:00 +01003787
Larry Hastings2f936352014-08-05 14:04:04 +10003788/*[clinic input]
3789os._getvolumepathname
3790
3791 path: unicode
3792
3793A helper function for ismount on Win32.
3794[clinic start generated code]*/
3795
Larry Hastings2f936352014-08-05 14:04:04 +10003796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003797os__getvolumepathname_impl(PyObject *module, PyObject *path)
3798/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003799{
3800 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003801 const wchar_t *path_wchar;
3802 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003803 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003804 BOOL ret;
3805
Larry Hastings2f936352014-08-05 14:04:04 +10003806 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3807 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003808 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003809 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003810
3811 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003812 buflen = Py_MAX(buflen, MAX_PATH);
3813
Victor Stinner850a18e2017-10-24 16:53:32 -07003814 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003815 PyErr_SetString(PyExc_OverflowError, "path too long");
3816 return NULL;
3817 }
3818
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003819 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003820 if (mountpath == NULL)
3821 return PyErr_NoMemory();
3822
3823 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003824 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003825 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003826 Py_END_ALLOW_THREADS
3827
3828 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003829 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003830 goto exit;
3831 }
3832 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3833
3834exit:
3835 PyMem_Free(mountpath);
3836 return result;
3837}
Tim Golden6b528062013-08-01 12:44:00 +01003838
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003839#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003840
Larry Hastings2f936352014-08-05 14:04:04 +10003841
3842/*[clinic input]
3843os.mkdir
3844
3845 path : path_t
3846
3847 mode: int = 0o777
3848
3849 *
3850
3851 dir_fd : dir_fd(requires='mkdirat') = None
3852
3853# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3854
3855Create a directory.
3856
3857If dir_fd is not None, it should be a file descriptor open to a directory,
3858 and path should be relative; path will then be relative to that directory.
3859dir_fd may not be implemented on your platform.
3860 If it is unavailable, using it will raise a NotImplementedError.
3861
3862The mode argument is ignored on Windows.
3863[clinic start generated code]*/
3864
Larry Hastings2f936352014-08-05 14:04:04 +10003865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003866os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3867/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003868{
3869 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003870
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003871#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003872 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003873 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003875
Larry Hastings2f936352014-08-05 14:04:04 +10003876 if (!result)
3877 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003878#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003880#if HAVE_MKDIRAT
3881 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003882 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003883 else
3884#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003885#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003886 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003887#else
Larry Hastings2f936352014-08-05 14:04:04 +10003888 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003889#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003890 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003891 if (result < 0)
3892 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003893#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003894 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003895}
3896
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003897
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003898/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3899#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003900#include <sys/resource.h>
3901#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003902
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003903
3904#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003905/*[clinic input]
3906os.nice
3907
3908 increment: int
3909 /
3910
3911Add increment to the priority of process and return the new priority.
3912[clinic start generated code]*/
3913
Larry Hastings2f936352014-08-05 14:04:04 +10003914static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003915os_nice_impl(PyObject *module, int increment)
3916/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003917{
3918 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003919
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 /* There are two flavours of 'nice': one that returns the new
3921 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003922 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003924
Victor Stinner8c62be82010-05-06 00:08:46 +00003925 If we are of the nice family that returns the new priority, we
3926 need to clear errno before the call, and check if errno is filled
3927 before calling posix_error() on a returnvalue of -1, because the
3928 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003929
Victor Stinner8c62be82010-05-06 00:08:46 +00003930 errno = 0;
3931 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003932#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003933 if (value == 0)
3934 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003935#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003936 if (value == -1 && errno != 0)
3937 /* either nice() or getpriority() returned an error */
3938 return posix_error();
3939 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003940}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003941#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003942
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003943
3944#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003945/*[clinic input]
3946os.getpriority
3947
3948 which: int
3949 who: int
3950
3951Return program scheduling priority.
3952[clinic start generated code]*/
3953
Larry Hastings2f936352014-08-05 14:04:04 +10003954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003955os_getpriority_impl(PyObject *module, int which, int who)
3956/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003957{
3958 int retval;
3959
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003960 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003961 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003962 if (errno != 0)
3963 return posix_error();
3964 return PyLong_FromLong((long)retval);
3965}
3966#endif /* HAVE_GETPRIORITY */
3967
3968
3969#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003970/*[clinic input]
3971os.setpriority
3972
3973 which: int
3974 who: int
3975 priority: int
3976
3977Set program scheduling priority.
3978[clinic start generated code]*/
3979
Larry Hastings2f936352014-08-05 14:04:04 +10003980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003981os_setpriority_impl(PyObject *module, int which, int who, int priority)
3982/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003983{
3984 int retval;
3985
3986 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003987 if (retval == -1)
3988 return posix_error();
3989 Py_RETURN_NONE;
3990}
3991#endif /* HAVE_SETPRIORITY */
3992
3993
Barry Warsaw53699e91996-12-10 23:23:01 +00003994static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003995internal_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 +00003996{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003997 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004000#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004001 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004002 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004003#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004004 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004005#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4008 (dst_dir_fd != DEFAULT_DIR_FD);
4009#ifndef HAVE_RENAMEAT
4010 if (dir_fd_specified) {
4011 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004012 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013 }
4014#endif
4015
Larry Hastings9cf065c2012-06-22 16:30:09 -07004016#ifdef MS_WINDOWS
4017 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004018 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004019 Py_END_ALLOW_THREADS
4020
Larry Hastings2f936352014-08-05 14:04:04 +10004021 if (!result)
4022 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004023
4024#else
Steve Dowercc16be82016-09-08 10:35:16 -07004025 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4026 PyErr_Format(PyExc_ValueError,
4027 "%s: src and dst must be the same type", function_name);
4028 return NULL;
4029 }
4030
Larry Hastings9cf065c2012-06-22 16:30:09 -07004031 Py_BEGIN_ALLOW_THREADS
4032#ifdef HAVE_RENAMEAT
4033 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004034 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004035 else
4036#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004037 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004038 Py_END_ALLOW_THREADS
4039
Larry Hastings2f936352014-08-05 14:04:04 +10004040 if (result)
4041 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004043 Py_RETURN_NONE;
4044}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004045
Larry Hastings2f936352014-08-05 14:04:04 +10004046
4047/*[clinic input]
4048os.rename
4049
4050 src : path_t
4051 dst : path_t
4052 *
4053 src_dir_fd : dir_fd = None
4054 dst_dir_fd : dir_fd = None
4055
4056Rename a file or directory.
4057
4058If either src_dir_fd or dst_dir_fd is not None, it should be a file
4059 descriptor open to a directory, and the respective path string (src or dst)
4060 should be relative; the path will then be relative to that directory.
4061src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4062 If they are unavailable, using them will raise a NotImplementedError.
4063[clinic start generated code]*/
4064
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004065static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004066os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004067 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004068/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004069{
Larry Hastings2f936352014-08-05 14:04:04 +10004070 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004071}
4072
Larry Hastings2f936352014-08-05 14:04:04 +10004073
4074/*[clinic input]
4075os.replace = os.rename
4076
4077Rename a file or directory, overwriting the destination.
4078
4079If either src_dir_fd or dst_dir_fd is not None, it should be a file
4080 descriptor open to a directory, and the respective path string (src or dst)
4081 should be relative; the path will then be relative to that directory.
4082src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4083 If they are unavailable, using them will raise a NotImplementedError."
4084[clinic start generated code]*/
4085
Larry Hastings2f936352014-08-05 14:04:04 +10004086static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004087os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4088 int dst_dir_fd)
4089/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004090{
4091 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4092}
4093
4094
4095/*[clinic input]
4096os.rmdir
4097
4098 path: path_t
4099 *
4100 dir_fd: dir_fd(requires='unlinkat') = None
4101
4102Remove a directory.
4103
4104If dir_fd is not None, it should be a file descriptor open to a directory,
4105 and path should be relative; path will then be relative to that directory.
4106dir_fd may not be implemented on your platform.
4107 If it is unavailable, using it will raise a NotImplementedError.
4108[clinic start generated code]*/
4109
Larry Hastings2f936352014-08-05 14:04:04 +10004110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004111os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4112/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004113{
4114 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004115
4116 Py_BEGIN_ALLOW_THREADS
4117#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004118 /* Windows, success=1, UNIX, success=0 */
4119 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004120#else
4121#ifdef HAVE_UNLINKAT
4122 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004123 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004124 else
4125#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004126 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004127#endif
4128 Py_END_ALLOW_THREADS
4129
Larry Hastings2f936352014-08-05 14:04:04 +10004130 if (result)
4131 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004132
Larry Hastings2f936352014-08-05 14:04:04 +10004133 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004134}
4135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004136
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004137#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004138#ifdef MS_WINDOWS
4139/*[clinic input]
4140os.system -> long
4141
4142 command: Py_UNICODE
4143
4144Execute the command in a subshell.
4145[clinic start generated code]*/
4146
Larry Hastings2f936352014-08-05 14:04:04 +10004147static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004148os_system_impl(PyObject *module, Py_UNICODE *command)
4149/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004150{
4151 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004152 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004153 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004154 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004155 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004157 return result;
4158}
4159#else /* MS_WINDOWS */
4160/*[clinic input]
4161os.system -> long
4162
4163 command: FSConverter
4164
4165Execute the command in a subshell.
4166[clinic start generated code]*/
4167
Larry Hastings2f936352014-08-05 14:04:04 +10004168static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004169os_system_impl(PyObject *module, PyObject *command)
4170/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004171{
4172 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004173 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004174 Py_BEGIN_ALLOW_THREADS
4175 result = system(bytes);
4176 Py_END_ALLOW_THREADS
4177 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004178}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004179#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004180#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004182
Larry Hastings2f936352014-08-05 14:04:04 +10004183/*[clinic input]
4184os.umask
4185
4186 mask: int
4187 /
4188
4189Set the current numeric umask and return the previous umask.
4190[clinic start generated code]*/
4191
Larry Hastings2f936352014-08-05 14:04:04 +10004192static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004193os_umask_impl(PyObject *module, int mask)
4194/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004195{
4196 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004197 if (i < 0)
4198 return posix_error();
4199 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004200}
4201
Brian Curtind40e6f72010-07-08 21:39:08 +00004202#ifdef MS_WINDOWS
4203
4204/* override the default DeleteFileW behavior so that directory
4205symlinks can be removed with this function, the same as with
4206Unix symlinks */
4207BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4208{
4209 WIN32_FILE_ATTRIBUTE_DATA info;
4210 WIN32_FIND_DATAW find_data;
4211 HANDLE find_data_handle;
4212 int is_directory = 0;
4213 int is_link = 0;
4214
4215 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4216 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004217
Brian Curtind40e6f72010-07-08 21:39:08 +00004218 /* Get WIN32_FIND_DATA structure for the path to determine if
4219 it is a symlink */
4220 if(is_directory &&
4221 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4222 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4223
4224 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004225 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4226 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4227 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4228 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004229 FindClose(find_data_handle);
4230 }
4231 }
4232 }
4233
4234 if (is_directory && is_link)
4235 return RemoveDirectoryW(lpFileName);
4236
4237 return DeleteFileW(lpFileName);
4238}
4239#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Larry Hastings2f936352014-08-05 14:04:04 +10004242/*[clinic input]
4243os.unlink
4244
4245 path: path_t
4246 *
4247 dir_fd: dir_fd(requires='unlinkat')=None
4248
4249Remove a file (same as remove()).
4250
4251If dir_fd is not None, it should be a file descriptor open to a directory,
4252 and path should be relative; path will then be relative to that directory.
4253dir_fd may not be implemented on your platform.
4254 If it is unavailable, using it will raise a NotImplementedError.
4255
4256[clinic start generated code]*/
4257
Larry Hastings2f936352014-08-05 14:04:04 +10004258static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004259os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4260/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004261{
4262 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004263
4264 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004265 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004266#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004267 /* Windows, success=1, UNIX, success=0 */
4268 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004270#ifdef HAVE_UNLINKAT
4271 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004272 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004273 else
4274#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004275 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004276#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004277 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004278 Py_END_ALLOW_THREADS
4279
Larry Hastings2f936352014-08-05 14:04:04 +10004280 if (result)
4281 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004282
Larry Hastings2f936352014-08-05 14:04:04 +10004283 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004284}
4285
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004286
Larry Hastings2f936352014-08-05 14:04:04 +10004287/*[clinic input]
4288os.remove = os.unlink
4289
4290Remove a file (same as unlink()).
4291
4292If dir_fd is not None, it should be a file descriptor open to a directory,
4293 and path should be relative; path will then be relative to that directory.
4294dir_fd may not be implemented on your platform.
4295 If it is unavailable, using it will raise a NotImplementedError.
4296[clinic start generated code]*/
4297
Larry Hastings2f936352014-08-05 14:04:04 +10004298static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004299os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4300/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004301{
4302 return os_unlink_impl(module, path, dir_fd);
4303}
4304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004305
Larry Hastings605a62d2012-06-24 04:33:36 -07004306static PyStructSequence_Field uname_result_fields[] = {
4307 {"sysname", "operating system name"},
4308 {"nodename", "name of machine on network (implementation-defined)"},
4309 {"release", "operating system release"},
4310 {"version", "operating system version"},
4311 {"machine", "hardware identifier"},
4312 {NULL}
4313};
4314
4315PyDoc_STRVAR(uname_result__doc__,
4316"uname_result: Result from os.uname().\n\n\
4317This object may be accessed either as a tuple of\n\
4318 (sysname, nodename, release, version, machine),\n\
4319or via the attributes sysname, nodename, release, version, and machine.\n\
4320\n\
4321See os.uname for more information.");
4322
4323static PyStructSequence_Desc uname_result_desc = {
4324 "uname_result", /* name */
4325 uname_result__doc__, /* doc */
4326 uname_result_fields,
4327 5
4328};
4329
4330static PyTypeObject UnameResultType;
4331
4332
4333#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004334/*[clinic input]
4335os.uname
4336
4337Return an object identifying the current operating system.
4338
4339The object behaves like a named tuple with the following fields:
4340 (sysname, nodename, release, version, machine)
4341
4342[clinic start generated code]*/
4343
Larry Hastings2f936352014-08-05 14:04:04 +10004344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004345os_uname_impl(PyObject *module)
4346/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004347{
Victor Stinner8c62be82010-05-06 00:08:46 +00004348 struct utsname u;
4349 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004350 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004351
Victor Stinner8c62be82010-05-06 00:08:46 +00004352 Py_BEGIN_ALLOW_THREADS
4353 res = uname(&u);
4354 Py_END_ALLOW_THREADS
4355 if (res < 0)
4356 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004357
4358 value = PyStructSequence_New(&UnameResultType);
4359 if (value == NULL)
4360 return NULL;
4361
4362#define SET(i, field) \
4363 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004364 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004365 if (!o) { \
4366 Py_DECREF(value); \
4367 return NULL; \
4368 } \
4369 PyStructSequence_SET_ITEM(value, i, o); \
4370 } \
4371
4372 SET(0, u.sysname);
4373 SET(1, u.nodename);
4374 SET(2, u.release);
4375 SET(3, u.version);
4376 SET(4, u.machine);
4377
4378#undef SET
4379
4380 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004381}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004382#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004383
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004384
Larry Hastings9cf065c2012-06-22 16:30:09 -07004385
4386typedef struct {
4387 int now;
4388 time_t atime_s;
4389 long atime_ns;
4390 time_t mtime_s;
4391 long mtime_ns;
4392} utime_t;
4393
4394/*
Victor Stinner484df002014-10-09 13:52:31 +02004395 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396 * they also intentionally leak the declaration of a pointer named "time"
4397 */
4398#define UTIME_TO_TIMESPEC \
4399 struct timespec ts[2]; \
4400 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004401 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402 time = NULL; \
4403 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004404 ts[0].tv_sec = ut->atime_s; \
4405 ts[0].tv_nsec = ut->atime_ns; \
4406 ts[1].tv_sec = ut->mtime_s; \
4407 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004408 time = ts; \
4409 } \
4410
4411#define UTIME_TO_TIMEVAL \
4412 struct timeval tv[2]; \
4413 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004414 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004415 time = NULL; \
4416 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004417 tv[0].tv_sec = ut->atime_s; \
4418 tv[0].tv_usec = ut->atime_ns / 1000; \
4419 tv[1].tv_sec = ut->mtime_s; \
4420 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004421 time = tv; \
4422 } \
4423
4424#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004425 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004426 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004427 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004428 time = NULL; \
4429 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004430 u.actime = ut->atime_s; \
4431 u.modtime = ut->mtime_s; \
4432 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004433 }
4434
4435#define UTIME_TO_TIME_T \
4436 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004437 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004438 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 time = NULL; \
4440 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004441 timet[0] = ut->atime_s; \
4442 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004443 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 } \
4445
4446
Victor Stinner528a9ab2015-09-03 21:30:26 +02004447#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004448
4449static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004450utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451{
4452#ifdef HAVE_UTIMENSAT
4453 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4454 UTIME_TO_TIMESPEC;
4455 return utimensat(dir_fd, path, time, flags);
4456#elif defined(HAVE_FUTIMESAT)
4457 UTIME_TO_TIMEVAL;
4458 /*
4459 * follow_symlinks will never be false here;
4460 * we only allow !follow_symlinks and dir_fd together
4461 * if we have utimensat()
4462 */
4463 assert(follow_symlinks);
4464 return futimesat(dir_fd, path, time);
4465#endif
4466}
4467
Larry Hastings2f936352014-08-05 14:04:04 +10004468 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4469#else
4470 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004471#endif
4472
Victor Stinner528a9ab2015-09-03 21:30:26 +02004473#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004474
4475static int
Victor Stinner484df002014-10-09 13:52:31 +02004476utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004477{
4478#ifdef HAVE_FUTIMENS
4479 UTIME_TO_TIMESPEC;
4480 return futimens(fd, time);
4481#else
4482 UTIME_TO_TIMEVAL;
4483 return futimes(fd, time);
4484#endif
4485}
4486
Larry Hastings2f936352014-08-05 14:04:04 +10004487 #define PATH_UTIME_HAVE_FD 1
4488#else
4489 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490#endif
4491
Victor Stinner5ebae872015-09-22 01:29:33 +02004492#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4493# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4494#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004495
Victor Stinner4552ced2015-09-21 22:37:15 +02004496#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497
4498static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004499utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004500{
4501#ifdef HAVE_UTIMENSAT
4502 UTIME_TO_TIMESPEC;
4503 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4504#else
4505 UTIME_TO_TIMEVAL;
4506 return lutimes(path, time);
4507#endif
4508}
4509
4510#endif
4511
4512#ifndef MS_WINDOWS
4513
4514static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004515utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516{
4517#ifdef HAVE_UTIMENSAT
4518 UTIME_TO_TIMESPEC;
4519 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4520#elif defined(HAVE_UTIMES)
4521 UTIME_TO_TIMEVAL;
4522 return utimes(path, time);
4523#elif defined(HAVE_UTIME_H)
4524 UTIME_TO_UTIMBUF;
4525 return utime(path, time);
4526#else
4527 UTIME_TO_TIME_T;
4528 return utime(path, time);
4529#endif
4530}
4531
4532#endif
4533
Larry Hastings76ad59b2012-05-03 00:30:07 -07004534static int
4535split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4536{
4537 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004538 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004539 divmod = PyNumber_Divmod(py_long, billion);
4540 if (!divmod)
4541 goto exit;
4542 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4543 if ((*s == -1) && PyErr_Occurred())
4544 goto exit;
4545 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004546 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004547 goto exit;
4548
4549 result = 1;
4550exit:
4551 Py_XDECREF(divmod);
4552 return result;
4553}
4554
Larry Hastings2f936352014-08-05 14:04:04 +10004555
4556/*[clinic input]
4557os.utime
4558
4559 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4560 times: object = NULL
4561 *
4562 ns: object = NULL
4563 dir_fd: dir_fd(requires='futimensat') = None
4564 follow_symlinks: bool=True
4565
Martin Panter0ff89092015-09-09 01:56:53 +00004566# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004567
4568Set the access and modified time of path.
4569
4570path may always be specified as a string.
4571On some platforms, path may also be specified as an open file descriptor.
4572 If this functionality is unavailable, using it raises an exception.
4573
4574If times is not None, it must be a tuple (atime, mtime);
4575 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004576If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004577 atime_ns and mtime_ns should be expressed as integer nanoseconds
4578 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004579If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004580Specifying tuples for both times and ns is an error.
4581
4582If dir_fd is not None, it should be a file descriptor open to a directory,
4583 and path should be relative; path will then be relative to that directory.
4584If follow_symlinks is False, and the last element of the path is a symbolic
4585 link, utime will modify the symbolic link itself instead of the file the
4586 link points to.
4587It is an error to use dir_fd or follow_symlinks when specifying path
4588 as an open file descriptor.
4589dir_fd and follow_symlinks may not be available on your platform.
4590 If they are unavailable, using them will raise a NotImplementedError.
4591
4592[clinic start generated code]*/
4593
Larry Hastings2f936352014-08-05 14:04:04 +10004594static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004595os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4596 int dir_fd, int follow_symlinks)
4597/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004598{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004599#ifdef MS_WINDOWS
4600 HANDLE hFile;
4601 FILETIME atime, mtime;
4602#else
4603 int result;
4604#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004605
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004607 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004608
Christian Heimesb3c87242013-08-01 00:08:16 +02004609 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004610
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611 if (times && (times != Py_None) && ns) {
4612 PyErr_SetString(PyExc_ValueError,
4613 "utime: you may specify either 'times'"
4614 " or 'ns' but not both");
4615 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004616 }
4617
4618 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004619 time_t a_sec, m_sec;
4620 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004621 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004622 PyErr_SetString(PyExc_TypeError,
4623 "utime: 'times' must be either"
4624 " a tuple of two ints or None");
4625 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004626 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004628 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004629 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004630 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004631 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004633 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004634 utime.atime_s = a_sec;
4635 utime.atime_ns = a_nsec;
4636 utime.mtime_s = m_sec;
4637 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004638 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004640 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 PyErr_SetString(PyExc_TypeError,
4642 "utime: 'ns' must be a tuple of two ints");
4643 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004644 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004646 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004648 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 &utime.mtime_s, &utime.mtime_ns)) {
4650 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004651 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 }
4653 else {
4654 /* times and ns are both None/unspecified. use "now". */
4655 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004656 }
4657
Victor Stinner4552ced2015-09-21 22:37:15 +02004658#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 if (follow_symlinks_specified("utime", follow_symlinks))
4660 goto exit;
4661#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004662
Larry Hastings2f936352014-08-05 14:04:04 +10004663 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4664 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4665 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004666 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668#if !defined(HAVE_UTIMENSAT)
4669 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004670 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 "utime: cannot use dir_fd and follow_symlinks "
4672 "together on this platform");
4673 goto exit;
4674 }
4675#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004676
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004677#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004679 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4680 NULL, OPEN_EXISTING,
4681 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 Py_END_ALLOW_THREADS
4683 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004684 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004686 }
4687
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004689 GetSystemTimeAsFileTime(&mtime);
4690 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004691 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004692 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004693 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4694 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004695 }
4696 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4697 /* Avoid putting the file name into the error here,
4698 as that may confuse the user into believing that
4699 something is wrong with the file, when it also
4700 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004701 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004703 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004704#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004705 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004706
Victor Stinner4552ced2015-09-21 22:37:15 +02004707#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004709 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004711#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712
Victor Stinner528a9ab2015-09-03 21:30:26 +02004713#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004715 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 else
4717#endif
4718
Victor Stinner528a9ab2015-09-03 21:30:26 +02004719#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004720 if (path->fd != -1)
4721 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 else
4723#endif
4724
Larry Hastings2f936352014-08-05 14:04:04 +10004725 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726
4727 Py_END_ALLOW_THREADS
4728
4729 if (result < 0) {
4730 /* see previous comment about not putting filename in error here */
4731 return_value = posix_error();
4732 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004734
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004735#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736
4737 Py_INCREF(Py_None);
4738 return_value = Py_None;
4739
4740exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741#ifdef MS_WINDOWS
4742 if (hFile != INVALID_HANDLE_VALUE)
4743 CloseHandle(hFile);
4744#endif
4745 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004746}
4747
Guido van Rossum3b066191991-06-04 19:40:25 +00004748/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004749
Larry Hastings2f936352014-08-05 14:04:04 +10004750
4751/*[clinic input]
4752os._exit
4753
4754 status: int
4755
4756Exit to the system with specified status, without normal exit processing.
4757[clinic start generated code]*/
4758
Larry Hastings2f936352014-08-05 14:04:04 +10004759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004760os__exit_impl(PyObject *module, int status)
4761/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004762{
4763 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004764 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004765}
4766
Steve Dowercc16be82016-09-08 10:35:16 -07004767#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4768#define EXECV_CHAR wchar_t
4769#else
4770#define EXECV_CHAR char
4771#endif
4772
Martin v. Löwis114619e2002-10-07 06:44:21 +00004773#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4774static void
Steve Dowercc16be82016-09-08 10:35:16 -07004775free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004776{
Victor Stinner8c62be82010-05-06 00:08:46 +00004777 Py_ssize_t i;
4778 for (i = 0; i < count; i++)
4779 PyMem_Free(array[i]);
4780 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004781}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004782
Berker Peksag81816462016-09-15 20:19:47 +03004783static int
4784fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004785{
Victor Stinner8c62be82010-05-06 00:08:46 +00004786 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004787 PyObject *ub;
4788 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004789#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004790 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004791 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004792 *out = PyUnicode_AsWideCharString(ub, &size);
4793 if (*out)
4794 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004795#else
Berker Peksag81816462016-09-15 20:19:47 +03004796 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004798 size = PyBytes_GET_SIZE(ub);
4799 *out = PyMem_Malloc(size + 1);
4800 if (*out) {
4801 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4802 result = 1;
4803 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004804 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004805#endif
Berker Peksag81816462016-09-15 20:19:47 +03004806 Py_DECREF(ub);
4807 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004808}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004809#endif
4810
Ross Lagerwall7807c352011-03-17 20:20:30 +02004811#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004812static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004813parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4814{
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 Py_ssize_t i, pos, envc;
4816 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004817 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004818 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004819
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 i = PyMapping_Size(env);
4821 if (i < 0)
4822 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004823 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 if (envlist == NULL) {
4825 PyErr_NoMemory();
4826 return NULL;
4827 }
4828 envc = 0;
4829 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004830 if (!keys)
4831 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004833 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 goto error;
4835 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4836 PyErr_Format(PyExc_TypeError,
4837 "env.keys() or env.values() is not a list");
4838 goto error;
4839 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004840
Victor Stinner8c62be82010-05-06 00:08:46 +00004841 for (pos = 0; pos < i; pos++) {
4842 key = PyList_GetItem(keys, pos);
4843 val = PyList_GetItem(vals, pos);
4844 if (!key || !val)
4845 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004846
Berker Peksag81816462016-09-15 20:19:47 +03004847#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4848 if (!PyUnicode_FSDecoder(key, &key2))
4849 goto error;
4850 if (!PyUnicode_FSDecoder(val, &val2)) {
4851 Py_DECREF(key2);
4852 goto error;
4853 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004854 /* Search from index 1 because on Windows starting '=' is allowed for
4855 defining hidden environment variables. */
4856 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4857 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4858 {
4859 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004860 Py_DECREF(key2);
4861 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004862 goto error;
4863 }
Berker Peksag81816462016-09-15 20:19:47 +03004864 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4865#else
4866 if (!PyUnicode_FSConverter(key, &key2))
4867 goto error;
4868 if (!PyUnicode_FSConverter(val, &val2)) {
4869 Py_DECREF(key2);
4870 goto error;
4871 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004872 if (PyBytes_GET_SIZE(key2) == 0 ||
4873 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4874 {
4875 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004876 Py_DECREF(key2);
4877 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004878 goto error;
4879 }
Berker Peksag81816462016-09-15 20:19:47 +03004880 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4881 PyBytes_AS_STRING(val2));
4882#endif
4883 Py_DECREF(key2);
4884 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004885 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004887
4888 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4889 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 goto error;
4891 }
Berker Peksag81816462016-09-15 20:19:47 +03004892
Steve Dowercc16be82016-09-08 10:35:16 -07004893 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004894 }
4895 Py_DECREF(vals);
4896 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004897
Victor Stinner8c62be82010-05-06 00:08:46 +00004898 envlist[envc] = 0;
4899 *envc_ptr = envc;
4900 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004901
4902error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 Py_XDECREF(keys);
4904 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004905 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004906 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004907}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004908
Steve Dowercc16be82016-09-08 10:35:16 -07004909static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004910parse_arglist(PyObject* argv, Py_ssize_t *argc)
4911{
4912 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004913 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004914 if (argvlist == NULL) {
4915 PyErr_NoMemory();
4916 return NULL;
4917 }
4918 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004919 PyObject* item = PySequence_ITEM(argv, i);
4920 if (item == NULL)
4921 goto fail;
4922 if (!fsconvert_strdup(item, &argvlist[i])) {
4923 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004924 goto fail;
4925 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004926 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004927 }
4928 argvlist[*argc] = NULL;
4929 return argvlist;
4930fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004931 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004932 free_string_array(argvlist, *argc);
4933 return NULL;
4934}
Steve Dowercc16be82016-09-08 10:35:16 -07004935
Ross Lagerwall7807c352011-03-17 20:20:30 +02004936#endif
4937
Larry Hastings2f936352014-08-05 14:04:04 +10004938
Ross Lagerwall7807c352011-03-17 20:20:30 +02004939#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004940/*[clinic input]
4941os.execv
4942
Steve Dowercc16be82016-09-08 10:35:16 -07004943 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004944 Path of executable file.
4945 argv: object
4946 Tuple or list of strings.
4947 /
4948
4949Execute an executable path with arguments, replacing current process.
4950[clinic start generated code]*/
4951
Larry Hastings2f936352014-08-05 14:04:04 +10004952static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004953os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4954/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004955{
Steve Dowercc16be82016-09-08 10:35:16 -07004956 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004957 Py_ssize_t argc;
4958
4959 /* execv has two arguments: (path, argv), where
4960 argv is a list or tuple of strings. */
4961
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4963 PyErr_SetString(PyExc_TypeError,
4964 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004965 return NULL;
4966 }
4967 argc = PySequence_Size(argv);
4968 if (argc < 1) {
4969 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004970 return NULL;
4971 }
4972
4973 argvlist = parse_arglist(argv, &argc);
4974 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975 return NULL;
4976 }
Steve Dowerbce26262016-11-19 19:17:26 -08004977 if (!argvlist[0][0]) {
4978 PyErr_SetString(PyExc_ValueError,
4979 "execv() arg 2 first element cannot be empty");
4980 free_string_array(argvlist, argc);
4981 return NULL;
4982 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004983
Steve Dowerbce26262016-11-19 19:17:26 -08004984 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004985#ifdef HAVE_WEXECV
4986 _wexecv(path->wide, argvlist);
4987#else
4988 execv(path->narrow, argvlist);
4989#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004990 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004991
4992 /* If we get here it's definitely an error */
4993
4994 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004995 return posix_error();
4996}
4997
Larry Hastings2f936352014-08-05 14:04:04 +10004998
4999/*[clinic input]
5000os.execve
5001
5002 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5003 Path of executable file.
5004 argv: object
5005 Tuple or list of strings.
5006 env: object
5007 Dictionary of strings mapping to strings.
5008
5009Execute an executable path with arguments, replacing current process.
5010[clinic start generated code]*/
5011
Larry Hastings2f936352014-08-05 14:04:04 +10005012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005013os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5014/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005015{
Steve Dowercc16be82016-09-08 10:35:16 -07005016 EXECV_CHAR **argvlist = NULL;
5017 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005019
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 /* execve has three arguments: (path, argv, env), where
5021 argv is a list or tuple of strings and env is a dictionary
5022 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005023
Ross Lagerwall7807c352011-03-17 20:20:30 +02005024 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005026 "execve: argv must be a tuple or list");
5027 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005029 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005030 if (argc < 1) {
5031 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5032 return NULL;
5033 }
5034
Victor Stinner8c62be82010-05-06 00:08:46 +00005035 if (!PyMapping_Check(env)) {
5036 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005037 "execve: environment must be a mapping object");
5038 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005040
Ross Lagerwall7807c352011-03-17 20:20:30 +02005041 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005042 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005043 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 }
Steve Dowerbce26262016-11-19 19:17:26 -08005045 if (!argvlist[0][0]) {
5046 PyErr_SetString(PyExc_ValueError,
5047 "execve: argv first element cannot be empty");
5048 goto fail;
5049 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005050
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 envlist = parse_envlist(env, &envc);
5052 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 goto fail;
5054
Steve Dowerbce26262016-11-19 19:17:26 -08005055 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005056#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005057 if (path->fd > -1)
5058 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005059 else
5060#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005061#ifdef HAVE_WEXECV
5062 _wexecve(path->wide, argvlist, envlist);
5063#else
Larry Hastings2f936352014-08-05 14:04:04 +10005064 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005065#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005066 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005067
5068 /* If we get here it's definitely an error */
5069
Larry Hastings2f936352014-08-05 14:04:04 +10005070 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071
Steve Dowercc16be82016-09-08 10:35:16 -07005072 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005073 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005074 if (argvlist)
5075 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 return NULL;
5077}
Steve Dowercc16be82016-09-08 10:35:16 -07005078
Larry Hastings9cf065c2012-06-22 16:30:09 -07005079#endif /* HAVE_EXECV */
5080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005081
Steve Dowercc16be82016-09-08 10:35:16 -07005082#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005083/*[clinic input]
5084os.spawnv
5085
5086 mode: int
5087 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005088 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005089 Path of executable file.
5090 argv: object
5091 Tuple or list of strings.
5092 /
5093
5094Execute the program specified by path in a new process.
5095[clinic start generated code]*/
5096
Larry Hastings2f936352014-08-05 14:04:04 +10005097static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005098os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5099/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005100{
Steve Dowercc16be82016-09-08 10:35:16 -07005101 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005102 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005104 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005106
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 /* spawnv has three arguments: (mode, path, argv), where
5108 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005109
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 if (PyList_Check(argv)) {
5111 argc = PyList_Size(argv);
5112 getitem = PyList_GetItem;
5113 }
5114 else if (PyTuple_Check(argv)) {
5115 argc = PyTuple_Size(argv);
5116 getitem = PyTuple_GetItem;
5117 }
5118 else {
5119 PyErr_SetString(PyExc_TypeError,
5120 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005121 return NULL;
5122 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005123 if (argc == 0) {
5124 PyErr_SetString(PyExc_ValueError,
5125 "spawnv() arg 2 cannot be empty");
5126 return NULL;
5127 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005128
Steve Dowercc16be82016-09-08 10:35:16 -07005129 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 return PyErr_NoMemory();
5132 }
5133 for (i = 0; i < argc; i++) {
5134 if (!fsconvert_strdup((*getitem)(argv, i),
5135 &argvlist[i])) {
5136 free_string_array(argvlist, i);
5137 PyErr_SetString(
5138 PyExc_TypeError,
5139 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 return NULL;
5141 }
Steve Dower93ff8722016-11-19 19:03:54 -08005142 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005143 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005144 PyErr_SetString(
5145 PyExc_ValueError,
5146 "spawnv() arg 2 first element cannot be empty");
5147 return NULL;
5148 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 }
5150 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005151
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 if (mode == _OLD_P_OVERLAY)
5153 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005154
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005156 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005157#ifdef HAVE_WSPAWNV
5158 spawnval = _wspawnv(mode, path->wide, argvlist);
5159#else
5160 spawnval = _spawnv(mode, path->narrow, argvlist);
5161#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005162 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005164
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005166
Victor Stinner8c62be82010-05-06 00:08:46 +00005167 if (spawnval == -1)
5168 return posix_error();
5169 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005170 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005171}
5172
5173
Larry Hastings2f936352014-08-05 14:04:04 +10005174/*[clinic input]
5175os.spawnve
5176
5177 mode: int
5178 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005179 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005180 Path of executable file.
5181 argv: object
5182 Tuple or list of strings.
5183 env: object
5184 Dictionary of strings mapping to strings.
5185 /
5186
5187Execute the program specified by path in a new process.
5188[clinic start generated code]*/
5189
Larry Hastings2f936352014-08-05 14:04:04 +10005190static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005191os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005192 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005193/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005194{
Steve Dowercc16be82016-09-08 10:35:16 -07005195 EXECV_CHAR **argvlist;
5196 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005198 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005199 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005201 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 /* spawnve has four arguments: (mode, path, argv, env), where
5204 argv is a list or tuple of strings and env is a dictionary
5205 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005206
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 if (PyList_Check(argv)) {
5208 argc = PyList_Size(argv);
5209 getitem = PyList_GetItem;
5210 }
5211 else if (PyTuple_Check(argv)) {
5212 argc = PyTuple_Size(argv);
5213 getitem = PyTuple_GetItem;
5214 }
5215 else {
5216 PyErr_SetString(PyExc_TypeError,
5217 "spawnve() arg 2 must be a tuple or list");
5218 goto fail_0;
5219 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005220 if (argc == 0) {
5221 PyErr_SetString(PyExc_ValueError,
5222 "spawnve() arg 2 cannot be empty");
5223 goto fail_0;
5224 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 if (!PyMapping_Check(env)) {
5226 PyErr_SetString(PyExc_TypeError,
5227 "spawnve() arg 3 must be a mapping object");
5228 goto fail_0;
5229 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005230
Steve Dowercc16be82016-09-08 10:35:16 -07005231 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 if (argvlist == NULL) {
5233 PyErr_NoMemory();
5234 goto fail_0;
5235 }
5236 for (i = 0; i < argc; i++) {
5237 if (!fsconvert_strdup((*getitem)(argv, i),
5238 &argvlist[i]))
5239 {
5240 lastarg = i;
5241 goto fail_1;
5242 }
Steve Dowerbce26262016-11-19 19:17:26 -08005243 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005244 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005245 PyErr_SetString(
5246 PyExc_ValueError,
5247 "spawnv() arg 2 first element cannot be empty");
5248 goto fail_1;
5249 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005250 }
5251 lastarg = argc;
5252 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005253
Victor Stinner8c62be82010-05-06 00:08:46 +00005254 envlist = parse_envlist(env, &envc);
5255 if (envlist == NULL)
5256 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005257
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 if (mode == _OLD_P_OVERLAY)
5259 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005260
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005262 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005263#ifdef HAVE_WSPAWNV
5264 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5265#else
5266 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5267#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005268 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005269 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005270
Victor Stinner8c62be82010-05-06 00:08:46 +00005271 if (spawnval == -1)
5272 (void) posix_error();
5273 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005274 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005275
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 while (--envc >= 0)
5277 PyMem_DEL(envlist[envc]);
5278 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005279 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005280 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005281 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005282 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005283}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005284
Guido van Rossuma1065681999-01-25 23:20:23 +00005285#endif /* HAVE_SPAWNV */
5286
5287
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005288#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005289
5290/* Helper function to validate arguments.
5291 Returns 0 on success. non-zero on failure with a TypeError raised.
5292 If obj is non-NULL it must be callable. */
5293static int
5294check_null_or_callable(PyObject *obj, const char* obj_name)
5295{
5296 if (obj && !PyCallable_Check(obj)) {
5297 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5298 obj_name, Py_TYPE(obj)->tp_name);
5299 return -1;
5300 }
5301 return 0;
5302}
5303
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005304/*[clinic input]
5305os.register_at_fork
5306
Gregory P. Smith163468a2017-05-29 10:03:41 -07005307 *
5308 before: object=NULL
5309 A callable to be called in the parent before the fork() syscall.
5310 after_in_child: object=NULL
5311 A callable to be called in the child after fork().
5312 after_in_parent: object=NULL
5313 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005314
Gregory P. Smith163468a2017-05-29 10:03:41 -07005315Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005316
Gregory P. Smith163468a2017-05-29 10:03:41 -07005317'before' callbacks are called in reverse order.
5318'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005319
5320[clinic start generated code]*/
5321
5322static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005323os_register_at_fork_impl(PyObject *module, PyObject *before,
5324 PyObject *after_in_child, PyObject *after_in_parent)
5325/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005326{
5327 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005328
Gregory P. Smith163468a2017-05-29 10:03:41 -07005329 if (!before && !after_in_child && !after_in_parent) {
5330 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5331 return NULL;
5332 }
5333 if (check_null_or_callable(before, "before") ||
5334 check_null_or_callable(after_in_child, "after_in_child") ||
5335 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005336 return NULL;
5337 }
5338 interp = PyThreadState_Get()->interp;
5339
Gregory P. Smith163468a2017-05-29 10:03:41 -07005340 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005341 return NULL;
5342 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005343 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005344 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005345 }
5346 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5347 return NULL;
5348 }
5349 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005350}
5351#endif /* HAVE_FORK */
5352
5353
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005354#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005355/*[clinic input]
5356os.fork1
5357
5358Fork a child process with a single multiplexed (i.e., not bound) thread.
5359
5360Return 0 to child process and PID of child to parent process.
5361[clinic start generated code]*/
5362
Larry Hastings2f936352014-08-05 14:04:04 +10005363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005364os_fork1_impl(PyObject *module)
5365/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005366{
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005368
5369 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 pid = fork1();
5371 if (pid == 0) {
5372 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005373 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005374 } else {
5375 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005376 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005377 }
5378 if (pid == -1)
5379 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005380 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005381}
Larry Hastings2f936352014-08-05 14:04:04 +10005382#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005383
5384
Guido van Rossumad0ee831995-03-01 10:34:45 +00005385#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005386/*[clinic input]
5387os.fork
5388
5389Fork a child process.
5390
5391Return 0 to child process and PID of child to parent process.
5392[clinic start generated code]*/
5393
Larry Hastings2f936352014-08-05 14:04:04 +10005394static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005395os_fork_impl(PyObject *module)
5396/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005397{
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005399
5400 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005401 pid = fork();
5402 if (pid == 0) {
5403 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005404 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 } else {
5406 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005407 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 }
5409 if (pid == -1)
5410 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005412}
Larry Hastings2f936352014-08-05 14:04:04 +10005413#endif /* HAVE_FORK */
5414
Guido van Rossum85e3b011991-06-03 12:42:10 +00005415
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005416#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005417#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005418/*[clinic input]
5419os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005420
Larry Hastings2f936352014-08-05 14:04:04 +10005421 policy: int
5422
5423Get the maximum scheduling priority for policy.
5424[clinic start generated code]*/
5425
Larry Hastings2f936352014-08-05 14:04:04 +10005426static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005427os_sched_get_priority_max_impl(PyObject *module, int policy)
5428/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005429{
5430 int max;
5431
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005432 max = sched_get_priority_max(policy);
5433 if (max < 0)
5434 return posix_error();
5435 return PyLong_FromLong(max);
5436}
5437
Larry Hastings2f936352014-08-05 14:04:04 +10005438
5439/*[clinic input]
5440os.sched_get_priority_min
5441
5442 policy: int
5443
5444Get the minimum scheduling priority for policy.
5445[clinic start generated code]*/
5446
Larry Hastings2f936352014-08-05 14:04:04 +10005447static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005448os_sched_get_priority_min_impl(PyObject *module, int policy)
5449/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005450{
5451 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005452 if (min < 0)
5453 return posix_error();
5454 return PyLong_FromLong(min);
5455}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005456#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5457
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005458
Larry Hastings2f936352014-08-05 14:04:04 +10005459#ifdef HAVE_SCHED_SETSCHEDULER
5460/*[clinic input]
5461os.sched_getscheduler
5462 pid: pid_t
5463 /
5464
5465Get the scheduling policy for the process identifiedy by pid.
5466
5467Passing 0 for pid returns the scheduling policy for the calling process.
5468[clinic start generated code]*/
5469
Larry Hastings2f936352014-08-05 14:04:04 +10005470static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005471os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5472/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005473{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005474 int policy;
5475
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005476 policy = sched_getscheduler(pid);
5477 if (policy < 0)
5478 return posix_error();
5479 return PyLong_FromLong(policy);
5480}
Larry Hastings2f936352014-08-05 14:04:04 +10005481#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005482
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005483
5484#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005485/*[clinic input]
5486class os.sched_param "PyObject *" "&SchedParamType"
5487
5488@classmethod
5489os.sched_param.__new__
5490
5491 sched_priority: object
5492 A scheduling parameter.
5493
5494Current has only one field: sched_priority");
5495[clinic start generated code]*/
5496
Larry Hastings2f936352014-08-05 14:04:04 +10005497static PyObject *
5498os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005499/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005500{
5501 PyObject *res;
5502
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005503 res = PyStructSequence_New(type);
5504 if (!res)
5505 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005506 Py_INCREF(sched_priority);
5507 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005508 return res;
5509}
5510
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005511
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005512PyDoc_VAR(os_sched_param__doc__);
5513
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005514static PyStructSequence_Field sched_param_fields[] = {
5515 {"sched_priority", "the scheduling priority"},
5516 {0}
5517};
5518
5519static PyStructSequence_Desc sched_param_desc = {
5520 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005521 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005522 sched_param_fields,
5523 1
5524};
5525
5526static int
5527convert_sched_param(PyObject *param, struct sched_param *res)
5528{
5529 long priority;
5530
5531 if (Py_TYPE(param) != &SchedParamType) {
5532 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5533 return 0;
5534 }
5535 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5536 if (priority == -1 && PyErr_Occurred())
5537 return 0;
5538 if (priority > INT_MAX || priority < INT_MIN) {
5539 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5540 return 0;
5541 }
5542 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5543 return 1;
5544}
Larry Hastings2f936352014-08-05 14:04:04 +10005545#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005546
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005547
5548#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005549/*[clinic input]
5550os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005551
Larry Hastings2f936352014-08-05 14:04:04 +10005552 pid: pid_t
5553 policy: int
5554 param: sched_param
5555 /
5556
5557Set the scheduling policy for the process identified by pid.
5558
5559If pid is 0, the calling process is changed.
5560param is an instance of sched_param.
5561[clinic start generated code]*/
5562
Larry Hastings2f936352014-08-05 14:04:04 +10005563static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005564os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005565 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005566/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005567{
Jesus Cea9c822272011-09-10 01:40:52 +02005568 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005569 ** sched_setscheduler() returns 0 in Linux, but the previous
5570 ** scheduling policy under Solaris/Illumos, and others.
5571 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005572 */
Larry Hastings2f936352014-08-05 14:04:04 +10005573 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005574 return posix_error();
5575 Py_RETURN_NONE;
5576}
Larry Hastings2f936352014-08-05 14:04:04 +10005577#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005578
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005579
5580#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005581/*[clinic input]
5582os.sched_getparam
5583 pid: pid_t
5584 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005585
Larry Hastings2f936352014-08-05 14:04:04 +10005586Returns scheduling parameters for the process identified by pid.
5587
5588If pid is 0, returns parameters for the calling process.
5589Return value is an instance of sched_param.
5590[clinic start generated code]*/
5591
Larry Hastings2f936352014-08-05 14:04:04 +10005592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005593os_sched_getparam_impl(PyObject *module, pid_t pid)
5594/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005595{
5596 struct sched_param param;
5597 PyObject *result;
5598 PyObject *priority;
5599
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005600 if (sched_getparam(pid, &param))
5601 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005602 result = PyStructSequence_New(&SchedParamType);
5603 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005604 return NULL;
5605 priority = PyLong_FromLong(param.sched_priority);
5606 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005607 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005608 return NULL;
5609 }
Larry Hastings2f936352014-08-05 14:04:04 +10005610 PyStructSequence_SET_ITEM(result, 0, priority);
5611 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005612}
5613
Larry Hastings2f936352014-08-05 14:04:04 +10005614
5615/*[clinic input]
5616os.sched_setparam
5617 pid: pid_t
5618 param: sched_param
5619 /
5620
5621Set scheduling parameters for the process identified by pid.
5622
5623If pid is 0, sets parameters for the calling process.
5624param should be an instance of sched_param.
5625[clinic start generated code]*/
5626
Larry Hastings2f936352014-08-05 14:04:04 +10005627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005628os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005629 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005630/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005631{
5632 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005633 return posix_error();
5634 Py_RETURN_NONE;
5635}
Larry Hastings2f936352014-08-05 14:04:04 +10005636#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005638
5639#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005640/*[clinic input]
5641os.sched_rr_get_interval -> double
5642 pid: pid_t
5643 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005644
Larry Hastings2f936352014-08-05 14:04:04 +10005645Return the round-robin quantum for the process identified by pid, in seconds.
5646
5647Value returned is a float.
5648[clinic start generated code]*/
5649
Larry Hastings2f936352014-08-05 14:04:04 +10005650static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005651os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5652/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005653{
5654 struct timespec interval;
5655 if (sched_rr_get_interval(pid, &interval)) {
5656 posix_error();
5657 return -1.0;
5658 }
5659 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5660}
5661#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005662
Larry Hastings2f936352014-08-05 14:04:04 +10005663
5664/*[clinic input]
5665os.sched_yield
5666
5667Voluntarily relinquish the CPU.
5668[clinic start generated code]*/
5669
Larry Hastings2f936352014-08-05 14:04:04 +10005670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005671os_sched_yield_impl(PyObject *module)
5672/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005673{
5674 if (sched_yield())
5675 return posix_error();
5676 Py_RETURN_NONE;
5677}
5678
Benjamin Peterson2740af82011-08-02 17:41:34 -05005679#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005680/* The minimum number of CPUs allocated in a cpu_set_t */
5681static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005682
Larry Hastings2f936352014-08-05 14:04:04 +10005683/*[clinic input]
5684os.sched_setaffinity
5685 pid: pid_t
5686 mask : object
5687 /
5688
5689Set the CPU affinity of the process identified by pid to mask.
5690
5691mask should be an iterable of integers identifying CPUs.
5692[clinic start generated code]*/
5693
Larry Hastings2f936352014-08-05 14:04:04 +10005694static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005695os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5696/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005697{
Antoine Pitrou84869872012-08-04 16:16:35 +02005698 int ncpus;
5699 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005700 cpu_set_t *cpu_set = NULL;
5701 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005702
Larry Hastings2f936352014-08-05 14:04:04 +10005703 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005704 if (iterator == NULL)
5705 return NULL;
5706
5707 ncpus = NCPUS_START;
5708 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005709 cpu_set = CPU_ALLOC(ncpus);
5710 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005711 PyErr_NoMemory();
5712 goto error;
5713 }
Larry Hastings2f936352014-08-05 14:04:04 +10005714 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005715
5716 while ((item = PyIter_Next(iterator))) {
5717 long cpu;
5718 if (!PyLong_Check(item)) {
5719 PyErr_Format(PyExc_TypeError,
5720 "expected an iterator of ints, "
5721 "but iterator yielded %R",
5722 Py_TYPE(item));
5723 Py_DECREF(item);
5724 goto error;
5725 }
5726 cpu = PyLong_AsLong(item);
5727 Py_DECREF(item);
5728 if (cpu < 0) {
5729 if (!PyErr_Occurred())
5730 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5731 goto error;
5732 }
5733 if (cpu > INT_MAX - 1) {
5734 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5735 goto error;
5736 }
5737 if (cpu >= ncpus) {
5738 /* Grow CPU mask to fit the CPU number */
5739 int newncpus = ncpus;
5740 cpu_set_t *newmask;
5741 size_t newsetsize;
5742 while (newncpus <= cpu) {
5743 if (newncpus > INT_MAX / 2)
5744 newncpus = cpu + 1;
5745 else
5746 newncpus = newncpus * 2;
5747 }
5748 newmask = CPU_ALLOC(newncpus);
5749 if (newmask == NULL) {
5750 PyErr_NoMemory();
5751 goto error;
5752 }
5753 newsetsize = CPU_ALLOC_SIZE(newncpus);
5754 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005755 memcpy(newmask, cpu_set, setsize);
5756 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005757 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005758 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005759 ncpus = newncpus;
5760 }
Larry Hastings2f936352014-08-05 14:04:04 +10005761 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005762 }
5763 Py_CLEAR(iterator);
5764
Larry Hastings2f936352014-08-05 14:04:04 +10005765 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005766 posix_error();
5767 goto error;
5768 }
Larry Hastings2f936352014-08-05 14:04:04 +10005769 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005770 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005771
5772error:
Larry Hastings2f936352014-08-05 14:04:04 +10005773 if (cpu_set)
5774 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005775 Py_XDECREF(iterator);
5776 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005777}
5778
Larry Hastings2f936352014-08-05 14:04:04 +10005779
5780/*[clinic input]
5781os.sched_getaffinity
5782 pid: pid_t
5783 /
5784
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005785Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005786
5787The affinity is returned as a set of CPU identifiers.
5788[clinic start generated code]*/
5789
Larry Hastings2f936352014-08-05 14:04:04 +10005790static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005791os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005792/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005793{
Antoine Pitrou84869872012-08-04 16:16:35 +02005794 int cpu, ncpus, count;
5795 size_t setsize;
5796 cpu_set_t *mask = NULL;
5797 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005798
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 ncpus = NCPUS_START;
5800 while (1) {
5801 setsize = CPU_ALLOC_SIZE(ncpus);
5802 mask = CPU_ALLOC(ncpus);
5803 if (mask == NULL)
5804 return PyErr_NoMemory();
5805 if (sched_getaffinity(pid, setsize, mask) == 0)
5806 break;
5807 CPU_FREE(mask);
5808 if (errno != EINVAL)
5809 return posix_error();
5810 if (ncpus > INT_MAX / 2) {
5811 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5812 "a large enough CPU set");
5813 return NULL;
5814 }
5815 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005816 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005817
5818 res = PySet_New(NULL);
5819 if (res == NULL)
5820 goto error;
5821 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5822 if (CPU_ISSET_S(cpu, setsize, mask)) {
5823 PyObject *cpu_num = PyLong_FromLong(cpu);
5824 --count;
5825 if (cpu_num == NULL)
5826 goto error;
5827 if (PySet_Add(res, cpu_num)) {
5828 Py_DECREF(cpu_num);
5829 goto error;
5830 }
5831 Py_DECREF(cpu_num);
5832 }
5833 }
5834 CPU_FREE(mask);
5835 return res;
5836
5837error:
5838 if (mask)
5839 CPU_FREE(mask);
5840 Py_XDECREF(res);
5841 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005842}
5843
Benjamin Peterson2740af82011-08-02 17:41:34 -05005844#endif /* HAVE_SCHED_SETAFFINITY */
5845
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005846#endif /* HAVE_SCHED_H */
5847
Larry Hastings2f936352014-08-05 14:04:04 +10005848
Neal Norwitzb59798b2003-03-21 01:43:31 +00005849/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005850/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5851#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005852#define DEV_PTY_FILE "/dev/ptc"
5853#define HAVE_DEV_PTMX
5854#else
5855#define DEV_PTY_FILE "/dev/ptmx"
5856#endif
5857
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005858#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005859#ifdef HAVE_PTY_H
5860#include <pty.h>
5861#else
5862#ifdef HAVE_LIBUTIL_H
5863#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005864#else
5865#ifdef HAVE_UTIL_H
5866#include <util.h>
5867#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005868#endif /* HAVE_LIBUTIL_H */
5869#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005870#ifdef HAVE_STROPTS_H
5871#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005872#endif
5873#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005874
Larry Hastings2f936352014-08-05 14:04:04 +10005875
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005876#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005877/*[clinic input]
5878os.openpty
5879
5880Open a pseudo-terminal.
5881
5882Return a tuple of (master_fd, slave_fd) containing open file descriptors
5883for both the master and slave ends.
5884[clinic start generated code]*/
5885
Larry Hastings2f936352014-08-05 14:04:04 +10005886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005887os_openpty_impl(PyObject *module)
5888/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005889{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005890 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005891#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005893#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005894#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005896#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005897 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005898#endif
5899#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005900
Thomas Wouters70c21a12000-07-14 14:28:33 +00005901#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005902 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005903 goto posix_error;
5904
5905 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5906 goto error;
5907 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5908 goto error;
5909
Neal Norwitzb59798b2003-03-21 01:43:31 +00005910#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005911 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5912 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005913 goto posix_error;
5914 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5915 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005916
Victor Stinnerdaf45552013-08-28 00:53:59 +02005917 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005919 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005920
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005921#else
Victor Stinner000de532013-11-25 23:19:58 +01005922 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005924 goto posix_error;
5925
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005927
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 /* change permission of slave */
5929 if (grantpt(master_fd) < 0) {
5930 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005931 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005933
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 /* unlock slave */
5935 if (unlockpt(master_fd) < 0) {
5936 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005937 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005939
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005941
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 slave_name = ptsname(master_fd); /* get name of slave */
5943 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005944 goto posix_error;
5945
5946 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005947 if (slave_fd == -1)
5948 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005949
5950 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5951 goto posix_error;
5952
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005953#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5955 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005956#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005957 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005958#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005959#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005960#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005961
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005963
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964posix_error:
5965 posix_error();
5966error:
5967 if (master_fd != -1)
5968 close(master_fd);
5969 if (slave_fd != -1)
5970 close(slave_fd);
5971 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005972}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005973#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005974
Larry Hastings2f936352014-08-05 14:04:04 +10005975
Fred Drake8cef4cf2000-06-28 16:40:38 +00005976#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005977/*[clinic input]
5978os.forkpty
5979
5980Fork a new process with a new pseudo-terminal as controlling tty.
5981
5982Returns a tuple of (pid, master_fd).
5983Like fork(), return pid of 0 to the child process,
5984and pid of child to the parent process.
5985To both, return fd of newly opened pseudo-terminal.
5986[clinic start generated code]*/
5987
Larry Hastings2f936352014-08-05 14:04:04 +10005988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005989os_forkpty_impl(PyObject *module)
5990/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005991{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005992 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005994
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005995 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005996 pid = forkpty(&master_fd, NULL, NULL, NULL);
5997 if (pid == 0) {
5998 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005999 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 } else {
6001 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006002 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 }
6004 if (pid == -1)
6005 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006007}
Larry Hastings2f936352014-08-05 14:04:04 +10006008#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006009
Ross Lagerwall7807c352011-03-17 20:20:30 +02006010
Guido van Rossumad0ee831995-03-01 10:34:45 +00006011#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006012/*[clinic input]
6013os.getegid
6014
6015Return the current process's effective group id.
6016[clinic start generated code]*/
6017
Larry Hastings2f936352014-08-05 14:04:04 +10006018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006019os_getegid_impl(PyObject *module)
6020/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006021{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006022 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006023}
Larry Hastings2f936352014-08-05 14:04:04 +10006024#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006026
Guido van Rossumad0ee831995-03-01 10:34:45 +00006027#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006028/*[clinic input]
6029os.geteuid
6030
6031Return the current process's effective user id.
6032[clinic start generated code]*/
6033
Larry Hastings2f936352014-08-05 14:04:04 +10006034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006035os_geteuid_impl(PyObject *module)
6036/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006037{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006038 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006039}
Larry Hastings2f936352014-08-05 14:04:04 +10006040#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006042
Guido van Rossumad0ee831995-03-01 10:34:45 +00006043#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006044/*[clinic input]
6045os.getgid
6046
6047Return the current process's group id.
6048[clinic start generated code]*/
6049
Larry Hastings2f936352014-08-05 14:04:04 +10006050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006051os_getgid_impl(PyObject *module)
6052/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006053{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006054 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006055}
Larry Hastings2f936352014-08-05 14:04:04 +10006056#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006058
Berker Peksag39404992016-09-15 20:45:16 +03006059#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006060/*[clinic input]
6061os.getpid
6062
6063Return the current process id.
6064[clinic start generated code]*/
6065
Larry Hastings2f936352014-08-05 14:04:04 +10006066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006067os_getpid_impl(PyObject *module)
6068/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006069{
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006071}
Berker Peksag39404992016-09-15 20:45:16 +03006072#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006073
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006074#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006075
6076/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006077PyDoc_STRVAR(posix_getgrouplist__doc__,
6078"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6079Returns a list of groups to which a user belongs.\n\n\
6080 user: username to lookup\n\
6081 group: base group id of the user");
6082
6083static PyObject *
6084posix_getgrouplist(PyObject *self, PyObject *args)
6085{
6086#ifdef NGROUPS_MAX
6087#define MAX_GROUPS NGROUPS_MAX
6088#else
6089 /* defined to be 16 on Solaris7, so this should be a small number */
6090#define MAX_GROUPS 64
6091#endif
6092
6093 const char *user;
6094 int i, ngroups;
6095 PyObject *list;
6096#ifdef __APPLE__
6097 int *groups, basegid;
6098#else
6099 gid_t *groups, basegid;
6100#endif
6101 ngroups = MAX_GROUPS;
6102
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006103#ifdef __APPLE__
6104 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006105 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006106#else
6107 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6108 _Py_Gid_Converter, &basegid))
6109 return NULL;
6110#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006111
6112#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006113 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006114#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006115 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006116#endif
6117 if (groups == NULL)
6118 return PyErr_NoMemory();
6119
6120 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6121 PyMem_Del(groups);
6122 return posix_error();
6123 }
6124
6125 list = PyList_New(ngroups);
6126 if (list == NULL) {
6127 PyMem_Del(groups);
6128 return NULL;
6129 }
6130
6131 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006132#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006133 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006134#else
6135 PyObject *o = _PyLong_FromGid(groups[i]);
6136#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006137 if (o == NULL) {
6138 Py_DECREF(list);
6139 PyMem_Del(groups);
6140 return NULL;
6141 }
6142 PyList_SET_ITEM(list, i, o);
6143 }
6144
6145 PyMem_Del(groups);
6146
6147 return list;
6148}
Larry Hastings2f936352014-08-05 14:04:04 +10006149#endif /* HAVE_GETGROUPLIST */
6150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006151
Fred Drakec9680921999-12-13 16:37:25 +00006152#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006153/*[clinic input]
6154os.getgroups
6155
6156Return list of supplemental group IDs for the process.
6157[clinic start generated code]*/
6158
Larry Hastings2f936352014-08-05 14:04:04 +10006159static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006160os_getgroups_impl(PyObject *module)
6161/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006162{
6163 PyObject *result = NULL;
6164
Fred Drakec9680921999-12-13 16:37:25 +00006165#ifdef NGROUPS_MAX
6166#define MAX_GROUPS NGROUPS_MAX
6167#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006169#define MAX_GROUPS 64
6170#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006171 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006172
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006173 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006174 * This is a helper variable to store the intermediate result when
6175 * that happens.
6176 *
6177 * To keep the code readable the OSX behaviour is unconditional,
6178 * according to the POSIX spec this should be safe on all unix-y
6179 * systems.
6180 */
6181 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006182 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006183
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006184#ifdef __APPLE__
6185 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6186 * there are more groups than can fit in grouplist. Therefore, on OS X
6187 * always first call getgroups with length 0 to get the actual number
6188 * of groups.
6189 */
6190 n = getgroups(0, NULL);
6191 if (n < 0) {
6192 return posix_error();
6193 } else if (n <= MAX_GROUPS) {
6194 /* groups will fit in existing array */
6195 alt_grouplist = grouplist;
6196 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006197 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006198 if (alt_grouplist == NULL) {
6199 errno = EINVAL;
6200 return posix_error();
6201 }
6202 }
6203
6204 n = getgroups(n, alt_grouplist);
6205 if (n == -1) {
6206 if (alt_grouplist != grouplist) {
6207 PyMem_Free(alt_grouplist);
6208 }
6209 return posix_error();
6210 }
6211#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006212 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006213 if (n < 0) {
6214 if (errno == EINVAL) {
6215 n = getgroups(0, NULL);
6216 if (n == -1) {
6217 return posix_error();
6218 }
6219 if (n == 0) {
6220 /* Avoid malloc(0) */
6221 alt_grouplist = grouplist;
6222 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006223 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006224 if (alt_grouplist == NULL) {
6225 errno = EINVAL;
6226 return posix_error();
6227 }
6228 n = getgroups(n, alt_grouplist);
6229 if (n == -1) {
6230 PyMem_Free(alt_grouplist);
6231 return posix_error();
6232 }
6233 }
6234 } else {
6235 return posix_error();
6236 }
6237 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006238#endif
6239
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006240 result = PyList_New(n);
6241 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006242 int i;
6243 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006244 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006246 Py_DECREF(result);
6247 result = NULL;
6248 break;
Fred Drakec9680921999-12-13 16:37:25 +00006249 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006251 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006252 }
6253
6254 if (alt_grouplist != grouplist) {
6255 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006257
Fred Drakec9680921999-12-13 16:37:25 +00006258 return result;
6259}
Larry Hastings2f936352014-08-05 14:04:04 +10006260#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006261
Antoine Pitroub7572f02009-12-02 20:46:48 +00006262#ifdef HAVE_INITGROUPS
6263PyDoc_STRVAR(posix_initgroups__doc__,
6264"initgroups(username, gid) -> None\n\n\
6265Call the system initgroups() to initialize the group access list with all of\n\
6266the groups of which the specified username is a member, plus the specified\n\
6267group id.");
6268
Larry Hastings2f936352014-08-05 14:04:04 +10006269/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006270static PyObject *
6271posix_initgroups(PyObject *self, PyObject *args)
6272{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006273 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006274 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006275 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006276#ifdef __APPLE__
6277 int gid;
6278#else
6279 gid_t gid;
6280#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006281
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006282#ifdef __APPLE__
6283 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6284 PyUnicode_FSConverter, &oname,
6285 &gid))
6286#else
6287 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6288 PyUnicode_FSConverter, &oname,
6289 _Py_Gid_Converter, &gid))
6290#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006292 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006293
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006294 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006295 Py_DECREF(oname);
6296 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006298
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006299 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006300}
Larry Hastings2f936352014-08-05 14:04:04 +10006301#endif /* HAVE_INITGROUPS */
6302
Antoine Pitroub7572f02009-12-02 20:46:48 +00006303
Martin v. Löwis606edc12002-06-13 21:09:11 +00006304#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006305/*[clinic input]
6306os.getpgid
6307
6308 pid: pid_t
6309
6310Call the system call getpgid(), and return the result.
6311[clinic start generated code]*/
6312
Larry Hastings2f936352014-08-05 14:04:04 +10006313static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006314os_getpgid_impl(PyObject *module, pid_t pid)
6315/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006316{
6317 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 if (pgid < 0)
6319 return posix_error();
6320 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006321}
6322#endif /* HAVE_GETPGID */
6323
6324
Guido van Rossumb6775db1994-08-01 11:34:53 +00006325#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006326/*[clinic input]
6327os.getpgrp
6328
6329Return the current process group id.
6330[clinic start generated code]*/
6331
Larry Hastings2f936352014-08-05 14:04:04 +10006332static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006333os_getpgrp_impl(PyObject *module)
6334/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006335{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006336#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006338#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006340#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006341}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006342#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006344
Guido van Rossumb6775db1994-08-01 11:34:53 +00006345#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006346/*[clinic input]
6347os.setpgrp
6348
6349Make the current process the leader of its process group.
6350[clinic start generated code]*/
6351
Larry Hastings2f936352014-08-05 14:04:04 +10006352static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006353os_setpgrp_impl(PyObject *module)
6354/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006355{
Guido van Rossum64933891994-10-20 21:56:42 +00006356#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006357 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006358#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006360#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006362 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006363}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006364#endif /* HAVE_SETPGRP */
6365
Guido van Rossumad0ee831995-03-01 10:34:45 +00006366#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006367
6368#ifdef MS_WINDOWS
6369#include <tlhelp32.h>
6370
6371static PyObject*
6372win32_getppid()
6373{
6374 HANDLE snapshot;
6375 pid_t mypid;
6376 PyObject* result = NULL;
6377 BOOL have_record;
6378 PROCESSENTRY32 pe;
6379
6380 mypid = getpid(); /* This function never fails */
6381
6382 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6383 if (snapshot == INVALID_HANDLE_VALUE)
6384 return PyErr_SetFromWindowsErr(GetLastError());
6385
6386 pe.dwSize = sizeof(pe);
6387 have_record = Process32First(snapshot, &pe);
6388 while (have_record) {
6389 if (mypid == (pid_t)pe.th32ProcessID) {
6390 /* We could cache the ulong value in a static variable. */
6391 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6392 break;
6393 }
6394
6395 have_record = Process32Next(snapshot, &pe);
6396 }
6397
6398 /* If our loop exits and our pid was not found (result will be NULL)
6399 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6400 * error anyway, so let's raise it. */
6401 if (!result)
6402 result = PyErr_SetFromWindowsErr(GetLastError());
6403
6404 CloseHandle(snapshot);
6405
6406 return result;
6407}
6408#endif /*MS_WINDOWS*/
6409
Larry Hastings2f936352014-08-05 14:04:04 +10006410
6411/*[clinic input]
6412os.getppid
6413
6414Return the parent's process id.
6415
6416If the parent process has already exited, Windows machines will still
6417return its id; others systems will return the id of the 'init' process (1).
6418[clinic start generated code]*/
6419
Larry Hastings2f936352014-08-05 14:04:04 +10006420static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006421os_getppid_impl(PyObject *module)
6422/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006423{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006424#ifdef MS_WINDOWS
6425 return win32_getppid();
6426#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006428#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006429}
6430#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006432
Fred Drake12c6e2d1999-12-14 21:25:03 +00006433#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006434/*[clinic input]
6435os.getlogin
6436
6437Return the actual login name.
6438[clinic start generated code]*/
6439
Larry Hastings2f936352014-08-05 14:04:04 +10006440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006441os_getlogin_impl(PyObject *module)
6442/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006443{
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006445#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006446 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006447 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006448
6449 if (GetUserNameW(user_name, &num_chars)) {
6450 /* num_chars is the number of unicode chars plus null terminator */
6451 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006452 }
6453 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006454 result = PyErr_SetFromWindowsErr(GetLastError());
6455#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006456 char *name;
6457 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006458
Victor Stinner8c62be82010-05-06 00:08:46 +00006459 errno = 0;
6460 name = getlogin();
6461 if (name == NULL) {
6462 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006463 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006464 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006465 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 }
6467 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006468 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006470#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006471 return result;
6472}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006473#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006474
Larry Hastings2f936352014-08-05 14:04:04 +10006475
Guido van Rossumad0ee831995-03-01 10:34:45 +00006476#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006477/*[clinic input]
6478os.getuid
6479
6480Return the current process's user id.
6481[clinic start generated code]*/
6482
Larry Hastings2f936352014-08-05 14:04:04 +10006483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006484os_getuid_impl(PyObject *module)
6485/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006486{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006487 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006488}
Larry Hastings2f936352014-08-05 14:04:04 +10006489#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006490
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006491
Brian Curtineb24d742010-04-12 17:16:38 +00006492#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006493#define HAVE_KILL
6494#endif /* MS_WINDOWS */
6495
6496#ifdef HAVE_KILL
6497/*[clinic input]
6498os.kill
6499
6500 pid: pid_t
6501 signal: Py_ssize_t
6502 /
6503
6504Kill a process with a signal.
6505[clinic start generated code]*/
6506
Larry Hastings2f936352014-08-05 14:04:04 +10006507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006508os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6509/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006510#ifndef MS_WINDOWS
6511{
6512 if (kill(pid, (int)signal) == -1)
6513 return posix_error();
6514 Py_RETURN_NONE;
6515}
6516#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006517{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006518 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006519 DWORD sig = (DWORD)signal;
6520 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006522
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 /* Console processes which share a common console can be sent CTRL+C or
6524 CTRL+BREAK events, provided they handle said events. */
6525 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006526 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006527 err = GetLastError();
6528 PyErr_SetFromWindowsErr(err);
6529 }
6530 else
6531 Py_RETURN_NONE;
6532 }
Brian Curtineb24d742010-04-12 17:16:38 +00006533
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6535 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006536 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 if (handle == NULL) {
6538 err = GetLastError();
6539 return PyErr_SetFromWindowsErr(err);
6540 }
Brian Curtineb24d742010-04-12 17:16:38 +00006541
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 if (TerminateProcess(handle, sig) == 0) {
6543 err = GetLastError();
6544 result = PyErr_SetFromWindowsErr(err);
6545 } else {
6546 Py_INCREF(Py_None);
6547 result = Py_None;
6548 }
Brian Curtineb24d742010-04-12 17:16:38 +00006549
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 CloseHandle(handle);
6551 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006552}
Larry Hastings2f936352014-08-05 14:04:04 +10006553#endif /* !MS_WINDOWS */
6554#endif /* HAVE_KILL */
6555
6556
6557#ifdef HAVE_KILLPG
6558/*[clinic input]
6559os.killpg
6560
6561 pgid: pid_t
6562 signal: int
6563 /
6564
6565Kill a process group with a signal.
6566[clinic start generated code]*/
6567
Larry Hastings2f936352014-08-05 14:04:04 +10006568static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006569os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6570/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006571{
6572 /* XXX some man pages make the `pgid` parameter an int, others
6573 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6574 take the same type. Moreover, pid_t is always at least as wide as
6575 int (else compilation of this module fails), which is safe. */
6576 if (killpg(pgid, signal) == -1)
6577 return posix_error();
6578 Py_RETURN_NONE;
6579}
6580#endif /* HAVE_KILLPG */
6581
Brian Curtineb24d742010-04-12 17:16:38 +00006582
Guido van Rossumc0125471996-06-28 18:55:32 +00006583#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006584#ifdef HAVE_SYS_LOCK_H
6585#include <sys/lock.h>
6586#endif
6587
Larry Hastings2f936352014-08-05 14:04:04 +10006588/*[clinic input]
6589os.plock
6590 op: int
6591 /
6592
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006593Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006594[clinic start generated code]*/
6595
Larry Hastings2f936352014-08-05 14:04:04 +10006596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006597os_plock_impl(PyObject *module, int op)
6598/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006599{
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 if (plock(op) == -1)
6601 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006602 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006603}
Larry Hastings2f936352014-08-05 14:04:04 +10006604#endif /* HAVE_PLOCK */
6605
Guido van Rossumc0125471996-06-28 18:55:32 +00006606
Guido van Rossumb6775db1994-08-01 11:34:53 +00006607#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006608/*[clinic input]
6609os.setuid
6610
6611 uid: uid_t
6612 /
6613
6614Set the current process's user id.
6615[clinic start generated code]*/
6616
Larry Hastings2f936352014-08-05 14:04:04 +10006617static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006618os_setuid_impl(PyObject *module, uid_t uid)
6619/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006620{
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 if (setuid(uid) < 0)
6622 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006623 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006624}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006625#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006626
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006627
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006628#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006629/*[clinic input]
6630os.seteuid
6631
6632 euid: uid_t
6633 /
6634
6635Set the current process's effective user id.
6636[clinic start generated code]*/
6637
Larry Hastings2f936352014-08-05 14:04:04 +10006638static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006639os_seteuid_impl(PyObject *module, uid_t euid)
6640/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006641{
6642 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006644 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006645}
6646#endif /* HAVE_SETEUID */
6647
Larry Hastings2f936352014-08-05 14:04:04 +10006648
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006649#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006650/*[clinic input]
6651os.setegid
6652
6653 egid: gid_t
6654 /
6655
6656Set the current process's effective group id.
6657[clinic start generated code]*/
6658
Larry Hastings2f936352014-08-05 14:04:04 +10006659static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006660os_setegid_impl(PyObject *module, gid_t egid)
6661/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006662{
6663 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006665 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006666}
6667#endif /* HAVE_SETEGID */
6668
Larry Hastings2f936352014-08-05 14:04:04 +10006669
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006670#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006671/*[clinic input]
6672os.setreuid
6673
6674 ruid: uid_t
6675 euid: uid_t
6676 /
6677
6678Set the current process's real and effective user ids.
6679[clinic start generated code]*/
6680
Larry Hastings2f936352014-08-05 14:04:04 +10006681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006682os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6683/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006684{
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 if (setreuid(ruid, euid) < 0) {
6686 return posix_error();
6687 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006688 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006690}
6691#endif /* HAVE_SETREUID */
6692
Larry Hastings2f936352014-08-05 14:04:04 +10006693
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006694#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006695/*[clinic input]
6696os.setregid
6697
6698 rgid: gid_t
6699 egid: gid_t
6700 /
6701
6702Set the current process's real and effective group ids.
6703[clinic start generated code]*/
6704
Larry Hastings2f936352014-08-05 14:04:04 +10006705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006706os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6707/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006708{
6709 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006711 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006712}
6713#endif /* HAVE_SETREGID */
6714
Larry Hastings2f936352014-08-05 14:04:04 +10006715
Guido van Rossumb6775db1994-08-01 11:34:53 +00006716#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006717/*[clinic input]
6718os.setgid
6719 gid: gid_t
6720 /
6721
6722Set the current process's group id.
6723[clinic start generated code]*/
6724
Larry Hastings2f936352014-08-05 14:04:04 +10006725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006726os_setgid_impl(PyObject *module, gid_t gid)
6727/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006728{
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 if (setgid(gid) < 0)
6730 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006731 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006732}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006733#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006734
Larry Hastings2f936352014-08-05 14:04:04 +10006735
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006736#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006737/*[clinic input]
6738os.setgroups
6739
6740 groups: object
6741 /
6742
6743Set the groups of the current process to list.
6744[clinic start generated code]*/
6745
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006747os_setgroups(PyObject *module, PyObject *groups)
6748/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006749{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006750 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006752
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 if (!PySequence_Check(groups)) {
6754 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6755 return NULL;
6756 }
6757 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006758 if (len < 0) {
6759 return NULL;
6760 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (len > MAX_GROUPS) {
6762 PyErr_SetString(PyExc_ValueError, "too many groups");
6763 return NULL;
6764 }
6765 for(i = 0; i < len; i++) {
6766 PyObject *elem;
6767 elem = PySequence_GetItem(groups, i);
6768 if (!elem)
6769 return NULL;
6770 if (!PyLong_Check(elem)) {
6771 PyErr_SetString(PyExc_TypeError,
6772 "groups must be integers");
6773 Py_DECREF(elem);
6774 return NULL;
6775 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006776 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 Py_DECREF(elem);
6778 return NULL;
6779 }
6780 }
6781 Py_DECREF(elem);
6782 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006783
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (setgroups(len, grouplist) < 0)
6785 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006786 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006787}
6788#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006789
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006790#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6791static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006792wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006793{
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 PyObject *result;
6795 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006796 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006797
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 if (pid == -1)
6799 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006800
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 if (struct_rusage == NULL) {
6802 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6803 if (m == NULL)
6804 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006805 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 Py_DECREF(m);
6807 if (struct_rusage == NULL)
6808 return NULL;
6809 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006810
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6812 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6813 if (!result)
6814 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815
6816#ifndef doubletime
6817#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6818#endif
6819
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006821 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006823 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006824#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6826 SET_INT(result, 2, ru->ru_maxrss);
6827 SET_INT(result, 3, ru->ru_ixrss);
6828 SET_INT(result, 4, ru->ru_idrss);
6829 SET_INT(result, 5, ru->ru_isrss);
6830 SET_INT(result, 6, ru->ru_minflt);
6831 SET_INT(result, 7, ru->ru_majflt);
6832 SET_INT(result, 8, ru->ru_nswap);
6833 SET_INT(result, 9, ru->ru_inblock);
6834 SET_INT(result, 10, ru->ru_oublock);
6835 SET_INT(result, 11, ru->ru_msgsnd);
6836 SET_INT(result, 12, ru->ru_msgrcv);
6837 SET_INT(result, 13, ru->ru_nsignals);
6838 SET_INT(result, 14, ru->ru_nvcsw);
6839 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006840#undef SET_INT
6841
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 if (PyErr_Occurred()) {
6843 Py_DECREF(result);
6844 return NULL;
6845 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006848}
6849#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6850
Larry Hastings2f936352014-08-05 14:04:04 +10006851
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006853/*[clinic input]
6854os.wait3
6855
6856 options: int
6857Wait for completion of a child process.
6858
6859Returns a tuple of information about the child process:
6860 (pid, status, rusage)
6861[clinic start generated code]*/
6862
Larry Hastings2f936352014-08-05 14:04:04 +10006863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006864os_wait3_impl(PyObject *module, int options)
6865/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866{
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006869 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 WAIT_TYPE status;
6871 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006873 do {
6874 Py_BEGIN_ALLOW_THREADS
6875 pid = wait3(&status, options, &ru);
6876 Py_END_ALLOW_THREADS
6877 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6878 if (pid < 0)
6879 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880
Victor Stinner4195b5c2012-02-08 23:03:19 +01006881 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882}
6883#endif /* HAVE_WAIT3 */
6884
Larry Hastings2f936352014-08-05 14:04:04 +10006885
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006887/*[clinic input]
6888
6889os.wait4
6890
6891 pid: pid_t
6892 options: int
6893
6894Wait for completion of a specific child process.
6895
6896Returns a tuple of information about the child process:
6897 (pid, status, rusage)
6898[clinic start generated code]*/
6899
Larry Hastings2f936352014-08-05 14:04:04 +10006900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006901os_wait4_impl(PyObject *module, pid_t pid, int options)
6902/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006903{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006904 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006906 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 WAIT_TYPE status;
6908 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006910 do {
6911 Py_BEGIN_ALLOW_THREADS
6912 res = wait4(pid, &status, options, &ru);
6913 Py_END_ALLOW_THREADS
6914 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6915 if (res < 0)
6916 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006918 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006919}
6920#endif /* HAVE_WAIT4 */
6921
Larry Hastings2f936352014-08-05 14:04:04 +10006922
Ross Lagerwall7807c352011-03-17 20:20:30 +02006923#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006924/*[clinic input]
6925os.waitid
6926
6927 idtype: idtype_t
6928 Must be one of be P_PID, P_PGID or P_ALL.
6929 id: id_t
6930 The id to wait on.
6931 options: int
6932 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6933 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6934 /
6935
6936Returns the result of waiting for a process or processes.
6937
6938Returns either waitid_result or None if WNOHANG is specified and there are
6939no children in a waitable state.
6940[clinic start generated code]*/
6941
Larry Hastings2f936352014-08-05 14:04:04 +10006942static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006943os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6944/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006945{
6946 PyObject *result;
6947 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006948 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006949 siginfo_t si;
6950 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006951
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006952 do {
6953 Py_BEGIN_ALLOW_THREADS
6954 res = waitid(idtype, id, &si, options);
6955 Py_END_ALLOW_THREADS
6956 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6957 if (res < 0)
6958 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006959
6960 if (si.si_pid == 0)
6961 Py_RETURN_NONE;
6962
6963 result = PyStructSequence_New(&WaitidResultType);
6964 if (!result)
6965 return NULL;
6966
6967 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006968 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006969 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6970 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6971 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6972 if (PyErr_Occurred()) {
6973 Py_DECREF(result);
6974 return NULL;
6975 }
6976
6977 return result;
6978}
Larry Hastings2f936352014-08-05 14:04:04 +10006979#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006980
Larry Hastings2f936352014-08-05 14:04:04 +10006981
6982#if defined(HAVE_WAITPID)
6983/*[clinic input]
6984os.waitpid
6985 pid: pid_t
6986 options: int
6987 /
6988
6989Wait for completion of a given child process.
6990
6991Returns a tuple of information regarding the child process:
6992 (pid, status)
6993
6994The options argument is ignored on Windows.
6995[clinic start generated code]*/
6996
Larry Hastings2f936352014-08-05 14:04:04 +10006997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006998os_waitpid_impl(PyObject *module, pid_t pid, int options)
6999/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007000{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007001 pid_t res;
7002 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 WAIT_TYPE status;
7004 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007005
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007006 do {
7007 Py_BEGIN_ALLOW_THREADS
7008 res = waitpid(pid, &status, options);
7009 Py_END_ALLOW_THREADS
7010 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7011 if (res < 0)
7012 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007013
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007014 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007015}
Tim Petersab034fa2002-02-01 11:27:43 +00007016#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007017/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007018/*[clinic input]
7019os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007020 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007021 options: int
7022 /
7023
7024Wait for completion of a given process.
7025
7026Returns a tuple of information regarding the process:
7027 (pid, status << 8)
7028
7029The options argument is ignored on Windows.
7030[clinic start generated code]*/
7031
Larry Hastings2f936352014-08-05 14:04:04 +10007032static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007033os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007034/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007035{
7036 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007037 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007038 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007039
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007040 do {
7041 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007042 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007043 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007044 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007045 Py_END_ALLOW_THREADS
7046 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007047 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007048 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007049
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007051 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007052}
Larry Hastings2f936352014-08-05 14:04:04 +10007053#endif
7054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007055
Guido van Rossumad0ee831995-03-01 10:34:45 +00007056#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007057/*[clinic input]
7058os.wait
7059
7060Wait for completion of a child process.
7061
7062Returns a tuple of information about the child process:
7063 (pid, status)
7064[clinic start generated code]*/
7065
Larry Hastings2f936352014-08-05 14:04:04 +10007066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007067os_wait_impl(PyObject *module)
7068/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007069{
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007071 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 WAIT_TYPE status;
7073 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007074
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007075 do {
7076 Py_BEGIN_ALLOW_THREADS
7077 pid = wait(&status);
7078 Py_END_ALLOW_THREADS
7079 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7080 if (pid < 0)
7081 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007082
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007084}
Larry Hastings2f936352014-08-05 14:04:04 +10007085#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007087
Larry Hastings9cf065c2012-06-22 16:30:09 -07007088#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7089PyDoc_STRVAR(readlink__doc__,
7090"readlink(path, *, dir_fd=None) -> path\n\n\
7091Return a string representing the path to which the symbolic link points.\n\
7092\n\
7093If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7094 and path should be relative; path will then be relative to that directory.\n\
7095dir_fd may not be implemented on your platform.\n\
7096 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007097#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007098
Guido van Rossumb6775db1994-08-01 11:34:53 +00007099#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007100
Larry Hastings2f936352014-08-05 14:04:04 +10007101/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007102static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007103posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007104{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105 path_t path;
7106 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007107 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108 ssize_t length;
7109 PyObject *return_value = NULL;
7110 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007111
Larry Hastings9cf065c2012-06-22 16:30:09 -07007112 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007113 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007114 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7115 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007116 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007118
Victor Stinner8c62be82010-05-06 00:08:46 +00007119 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120#ifdef HAVE_READLINKAT
7121 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007122 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007123 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007125 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126 Py_END_ALLOW_THREADS
7127
7128 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007129 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130 goto exit;
7131 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007132 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133
7134 if (PyUnicode_Check(path.object))
7135 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7136 else
7137 return_value = PyBytes_FromStringAndSize(buffer, length);
7138exit:
7139 path_cleanup(&path);
7140 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007141}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007142
Guido van Rossumb6775db1994-08-01 11:34:53 +00007143#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007144
Larry Hastings2f936352014-08-05 14:04:04 +10007145#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7146
7147static PyObject *
7148win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7149{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007150 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007151 DWORD n_bytes_returned;
7152 DWORD io_result;
7153 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007154 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007155 HANDLE reparse_point_handle;
7156
Martin Panter70214ad2016-08-04 02:38:59 +00007157 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7158 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007159 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007160
7161 static char *keywords[] = {"path", "dir_fd", NULL};
7162
7163 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7164 &po,
7165 dir_fd_unavailable, &dir_fd
7166 ))
7167 return NULL;
7168
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007169 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007170 if (path == NULL)
7171 return NULL;
7172
7173 /* First get a handle to the reparse point */
7174 Py_BEGIN_ALLOW_THREADS
7175 reparse_point_handle = CreateFileW(
7176 path,
7177 0,
7178 0,
7179 0,
7180 OPEN_EXISTING,
7181 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7182 0);
7183 Py_END_ALLOW_THREADS
7184
7185 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7186 return win32_error_object("readlink", po);
7187
7188 Py_BEGIN_ALLOW_THREADS
7189 /* New call DeviceIoControl to read the reparse point */
7190 io_result = DeviceIoControl(
7191 reparse_point_handle,
7192 FSCTL_GET_REPARSE_POINT,
7193 0, 0, /* in buffer */
7194 target_buffer, sizeof(target_buffer),
7195 &n_bytes_returned,
7196 0 /* we're not using OVERLAPPED_IO */
7197 );
7198 CloseHandle(reparse_point_handle);
7199 Py_END_ALLOW_THREADS
7200
7201 if (io_result==0)
7202 return win32_error_object("readlink", po);
7203
7204 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7205 {
7206 PyErr_SetString(PyExc_ValueError,
7207 "not a symbolic link");
7208 return NULL;
7209 }
7210 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7211 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7212
7213 result = PyUnicode_FromWideChar(print_name,
7214 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7215 return result;
7216}
7217
7218#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7219
7220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007221
Larry Hastings9cf065c2012-06-22 16:30:09 -07007222#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007223
7224#if defined(MS_WINDOWS)
7225
7226/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007227static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007228
Larry Hastings9cf065c2012-06-22 16:30:09 -07007229static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007230check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007231{
7232 HINSTANCE hKernel32;
7233 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007234 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007235 return 1;
7236 hKernel32 = GetModuleHandleW(L"KERNEL32");
7237 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7238 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007239 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007240}
7241
Victor Stinner31b3b922013-06-05 01:49:17 +02007242/* Remove the last portion of the path */
7243static void
7244_dirnameW(WCHAR *path)
7245{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007246 WCHAR *ptr;
7247
7248 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007249 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007250 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007251 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007252 }
7253 *ptr = 0;
7254}
7255
Victor Stinner31b3b922013-06-05 01:49:17 +02007256/* Is this path absolute? */
7257static int
7258_is_absW(const WCHAR *path)
7259{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007260 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7261
7262}
7263
Victor Stinner31b3b922013-06-05 01:49:17 +02007264/* join root and rest with a backslash */
7265static void
7266_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7267{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007268 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007269
Victor Stinner31b3b922013-06-05 01:49:17 +02007270 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007271 wcscpy(dest_path, rest);
7272 return;
7273 }
7274
7275 root_len = wcslen(root);
7276
7277 wcscpy(dest_path, root);
7278 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007279 dest_path[root_len] = L'\\';
7280 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007281 }
7282 wcscpy(dest_path+root_len, rest);
7283}
7284
Victor Stinner31b3b922013-06-05 01:49:17 +02007285/* Return True if the path at src relative to dest is a directory */
7286static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007287_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007288{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289 WIN32_FILE_ATTRIBUTE_DATA src_info;
7290 WCHAR dest_parent[MAX_PATH];
7291 WCHAR src_resolved[MAX_PATH] = L"";
7292
7293 /* dest_parent = os.path.dirname(dest) */
7294 wcscpy(dest_parent, dest);
7295 _dirnameW(dest_parent);
7296 /* src_resolved = os.path.join(dest_parent, src) */
7297 _joinW(src_resolved, dest_parent, src);
7298 return (
7299 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7300 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7301 );
7302}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007303#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007304
Larry Hastings2f936352014-08-05 14:04:04 +10007305
7306/*[clinic input]
7307os.symlink
7308 src: path_t
7309 dst: path_t
7310 target_is_directory: bool = False
7311 *
7312 dir_fd: dir_fd(requires='symlinkat')=None
7313
7314# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7315
7316Create a symbolic link pointing to src named dst.
7317
7318target_is_directory is required on Windows if the target is to be
7319 interpreted as a directory. (On Windows, symlink requires
7320 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7321 target_is_directory is ignored on non-Windows platforms.
7322
7323If dir_fd is not None, it should be a file descriptor open to a directory,
7324 and path should be relative; path will then be relative to that directory.
7325dir_fd may not be implemented on your platform.
7326 If it is unavailable, using it will raise a NotImplementedError.
7327
7328[clinic start generated code]*/
7329
Larry Hastings2f936352014-08-05 14:04:04 +10007330static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007331os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007332 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007333/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007334{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007335#ifdef MS_WINDOWS
7336 DWORD result;
7337#else
7338 int result;
7339#endif
7340
Larry Hastings9cf065c2012-06-22 16:30:09 -07007341#ifdef MS_WINDOWS
7342 if (!check_CreateSymbolicLink()) {
7343 PyErr_SetString(PyExc_NotImplementedError,
7344 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007345 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007346 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007347 if (!win32_can_symlink) {
7348 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007349 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007350 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007351#endif
7352
Larry Hastings2f936352014-08-05 14:04:04 +10007353 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007354 PyErr_SetString(PyExc_ValueError,
7355 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007356 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007357 }
7358
7359#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007360
Larry Hastings9cf065c2012-06-22 16:30:09 -07007361 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007362 /* if src is a directory, ensure target_is_directory==1 */
7363 target_is_directory |= _check_dirW(src->wide, dst->wide);
7364 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7365 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007366 Py_END_ALLOW_THREADS
7367
Larry Hastings2f936352014-08-05 14:04:04 +10007368 if (!result)
7369 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007370
7371#else
7372
7373 Py_BEGIN_ALLOW_THREADS
7374#if HAVE_SYMLINKAT
7375 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007376 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007377 else
7378#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007379 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007380 Py_END_ALLOW_THREADS
7381
Larry Hastings2f936352014-08-05 14:04:04 +10007382 if (result)
7383 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007384#endif
7385
Larry Hastings2f936352014-08-05 14:04:04 +10007386 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007387}
7388#endif /* HAVE_SYMLINK */
7389
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390
Brian Curtind40e6f72010-07-08 21:39:08 +00007391
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007392
Larry Hastings605a62d2012-06-24 04:33:36 -07007393static PyStructSequence_Field times_result_fields[] = {
7394 {"user", "user time"},
7395 {"system", "system time"},
7396 {"children_user", "user time of children"},
7397 {"children_system", "system time of children"},
7398 {"elapsed", "elapsed time since an arbitrary point in the past"},
7399 {NULL}
7400};
7401
7402PyDoc_STRVAR(times_result__doc__,
7403"times_result: Result from os.times().\n\n\
7404This object may be accessed either as a tuple of\n\
7405 (user, system, children_user, children_system, elapsed),\n\
7406or via the attributes user, system, children_user, children_system,\n\
7407and elapsed.\n\
7408\n\
7409See os.times for more information.");
7410
7411static PyStructSequence_Desc times_result_desc = {
7412 "times_result", /* name */
7413 times_result__doc__, /* doc */
7414 times_result_fields,
7415 5
7416};
7417
7418static PyTypeObject TimesResultType;
7419
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007420#ifdef MS_WINDOWS
7421#define HAVE_TIMES /* mandatory, for the method table */
7422#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007423
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007424#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007425
7426static PyObject *
7427build_times_result(double user, double system,
7428 double children_user, double children_system,
7429 double elapsed)
7430{
7431 PyObject *value = PyStructSequence_New(&TimesResultType);
7432 if (value == NULL)
7433 return NULL;
7434
7435#define SET(i, field) \
7436 { \
7437 PyObject *o = PyFloat_FromDouble(field); \
7438 if (!o) { \
7439 Py_DECREF(value); \
7440 return NULL; \
7441 } \
7442 PyStructSequence_SET_ITEM(value, i, o); \
7443 } \
7444
7445 SET(0, user);
7446 SET(1, system);
7447 SET(2, children_user);
7448 SET(3, children_system);
7449 SET(4, elapsed);
7450
7451#undef SET
7452
7453 return value;
7454}
7455
Larry Hastings605a62d2012-06-24 04:33:36 -07007456
Larry Hastings2f936352014-08-05 14:04:04 +10007457#ifndef MS_WINDOWS
7458#define NEED_TICKS_PER_SECOND
7459static long ticks_per_second = -1;
7460#endif /* MS_WINDOWS */
7461
7462/*[clinic input]
7463os.times
7464
7465Return a collection containing process timing information.
7466
7467The object returned behaves like a named tuple with these fields:
7468 (utime, stime, cutime, cstime, elapsed_time)
7469All fields are floating point numbers.
7470[clinic start generated code]*/
7471
Larry Hastings2f936352014-08-05 14:04:04 +10007472static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007473os_times_impl(PyObject *module)
7474/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007475#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007476{
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 FILETIME create, exit, kernel, user;
7478 HANDLE hProc;
7479 hProc = GetCurrentProcess();
7480 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7481 /* The fields of a FILETIME structure are the hi and lo part
7482 of a 64-bit value expressed in 100 nanosecond units.
7483 1e7 is one second in such units; 1e-7 the inverse.
7484 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7485 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007486 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007487 (double)(user.dwHighDateTime*429.4967296 +
7488 user.dwLowDateTime*1e-7),
7489 (double)(kernel.dwHighDateTime*429.4967296 +
7490 kernel.dwLowDateTime*1e-7),
7491 (double)0,
7492 (double)0,
7493 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007494}
Larry Hastings2f936352014-08-05 14:04:04 +10007495#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007496{
Larry Hastings2f936352014-08-05 14:04:04 +10007497
7498
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007499 struct tms t;
7500 clock_t c;
7501 errno = 0;
7502 c = times(&t);
7503 if (c == (clock_t) -1)
7504 return posix_error();
7505 return build_times_result(
7506 (double)t.tms_utime / ticks_per_second,
7507 (double)t.tms_stime / ticks_per_second,
7508 (double)t.tms_cutime / ticks_per_second,
7509 (double)t.tms_cstime / ticks_per_second,
7510 (double)c / ticks_per_second);
7511}
Larry Hastings2f936352014-08-05 14:04:04 +10007512#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007513#endif /* HAVE_TIMES */
7514
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007515
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007516#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007517/*[clinic input]
7518os.getsid
7519
7520 pid: pid_t
7521 /
7522
7523Call the system call getsid(pid) and return the result.
7524[clinic start generated code]*/
7525
Larry Hastings2f936352014-08-05 14:04:04 +10007526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007527os_getsid_impl(PyObject *module, pid_t pid)
7528/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007529{
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 sid = getsid(pid);
7532 if (sid < 0)
7533 return posix_error();
7534 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007535}
7536#endif /* HAVE_GETSID */
7537
7538
Guido van Rossumb6775db1994-08-01 11:34:53 +00007539#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007540/*[clinic input]
7541os.setsid
7542
7543Call the system call setsid().
7544[clinic start generated code]*/
7545
Larry Hastings2f936352014-08-05 14:04:04 +10007546static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007547os_setsid_impl(PyObject *module)
7548/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007549{
Victor Stinner8c62be82010-05-06 00:08:46 +00007550 if (setsid() < 0)
7551 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007552 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007553}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007554#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007555
Larry Hastings2f936352014-08-05 14:04:04 +10007556
Guido van Rossumb6775db1994-08-01 11:34:53 +00007557#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007558/*[clinic input]
7559os.setpgid
7560
7561 pid: pid_t
7562 pgrp: pid_t
7563 /
7564
7565Call the system call setpgid(pid, pgrp).
7566[clinic start generated code]*/
7567
Larry Hastings2f936352014-08-05 14:04:04 +10007568static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007569os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7570/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007571{
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 if (setpgid(pid, pgrp) < 0)
7573 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007574 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007575}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007576#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007578
Guido van Rossumb6775db1994-08-01 11:34:53 +00007579#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007580/*[clinic input]
7581os.tcgetpgrp
7582
7583 fd: int
7584 /
7585
7586Return the process group associated with the terminal specified by fd.
7587[clinic start generated code]*/
7588
Larry Hastings2f936352014-08-05 14:04:04 +10007589static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007590os_tcgetpgrp_impl(PyObject *module, int fd)
7591/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007592{
7593 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007594 if (pgid < 0)
7595 return posix_error();
7596 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007597}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007598#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007600
Guido van Rossumb6775db1994-08-01 11:34:53 +00007601#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007602/*[clinic input]
7603os.tcsetpgrp
7604
7605 fd: int
7606 pgid: pid_t
7607 /
7608
7609Set the process group associated with the terminal specified by fd.
7610[clinic start generated code]*/
7611
Larry Hastings2f936352014-08-05 14:04:04 +10007612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007613os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7614/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007615{
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 if (tcsetpgrp(fd, pgid) < 0)
7617 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007618 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007619}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007621
Guido van Rossum687dd131993-05-17 08:34:16 +00007622/* Functions acting on file descriptors */
7623
Victor Stinnerdaf45552013-08-28 00:53:59 +02007624#ifdef O_CLOEXEC
7625extern int _Py_open_cloexec_works;
7626#endif
7627
Larry Hastings2f936352014-08-05 14:04:04 +10007628
7629/*[clinic input]
7630os.open -> int
7631 path: path_t
7632 flags: int
7633 mode: int = 0o777
7634 *
7635 dir_fd: dir_fd(requires='openat') = None
7636
7637# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7638
7639Open a file for low level IO. Returns a file descriptor (integer).
7640
7641If dir_fd is not None, it should be a file descriptor open to a directory,
7642 and path should be relative; path will then be relative to that directory.
7643dir_fd may not be implemented on your platform.
7644 If it is unavailable, using it will raise a NotImplementedError.
7645[clinic start generated code]*/
7646
Larry Hastings2f936352014-08-05 14:04:04 +10007647static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007648os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7649/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007650{
7651 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007652 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007653
Victor Stinnerdaf45552013-08-28 00:53:59 +02007654#ifdef O_CLOEXEC
7655 int *atomic_flag_works = &_Py_open_cloexec_works;
7656#elif !defined(MS_WINDOWS)
7657 int *atomic_flag_works = NULL;
7658#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007659
Victor Stinnerdaf45552013-08-28 00:53:59 +02007660#ifdef MS_WINDOWS
7661 flags |= O_NOINHERIT;
7662#elif defined(O_CLOEXEC)
7663 flags |= O_CLOEXEC;
7664#endif
7665
Steve Dower8fc89802015-04-12 00:26:27 -04007666 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007667 do {
7668 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007669#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007670 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007671#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007672#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007673 if (dir_fd != DEFAULT_DIR_FD)
7674 fd = openat(dir_fd, path->narrow, flags, mode);
7675 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007676#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007677 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007678#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007679 Py_END_ALLOW_THREADS
7680 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007681 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007682
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007683 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007684 if (!async_err)
7685 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007686 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007687 }
7688
Victor Stinnerdaf45552013-08-28 00:53:59 +02007689#ifndef MS_WINDOWS
7690 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7691 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007692 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007693 }
7694#endif
7695
Larry Hastings2f936352014-08-05 14:04:04 +10007696 return fd;
7697}
7698
7699
7700/*[clinic input]
7701os.close
7702
7703 fd: int
7704
7705Close a file descriptor.
7706[clinic start generated code]*/
7707
Barry Warsaw53699e91996-12-10 23:23:01 +00007708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007709os_close_impl(PyObject *module, int fd)
7710/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007711{
Larry Hastings2f936352014-08-05 14:04:04 +10007712 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007713 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7714 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7715 * for more details.
7716 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007718 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007720 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007721 Py_END_ALLOW_THREADS
7722 if (res < 0)
7723 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007724 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007725}
7726
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007727
Larry Hastings2f936352014-08-05 14:04:04 +10007728/*[clinic input]
7729os.closerange
7730
7731 fd_low: int
7732 fd_high: int
7733 /
7734
7735Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7736[clinic start generated code]*/
7737
Larry Hastings2f936352014-08-05 14:04:04 +10007738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007739os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7740/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007741{
7742 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007744 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007745 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007746 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007747 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007748 Py_END_ALLOW_THREADS
7749 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007750}
7751
7752
Larry Hastings2f936352014-08-05 14:04:04 +10007753/*[clinic input]
7754os.dup -> int
7755
7756 fd: int
7757 /
7758
7759Return a duplicate of a file descriptor.
7760[clinic start generated code]*/
7761
Larry Hastings2f936352014-08-05 14:04:04 +10007762static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007763os_dup_impl(PyObject *module, int fd)
7764/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007765{
7766 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007767}
7768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007769
Larry Hastings2f936352014-08-05 14:04:04 +10007770/*[clinic input]
7771os.dup2
7772 fd: int
7773 fd2: int
7774 inheritable: bool=True
7775
7776Duplicate file descriptor.
7777[clinic start generated code]*/
7778
Larry Hastings2f936352014-08-05 14:04:04 +10007779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007780os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7781/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007782{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007783 int res;
7784#if defined(HAVE_DUP3) && \
7785 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7786 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7787 int dup3_works = -1;
7788#endif
7789
Steve Dower940f33a2016-09-08 11:21:54 -07007790 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007792
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007793 /* dup2() can fail with EINTR if the target FD is already open, because it
7794 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7795 * upon close(), and therefore below.
7796 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007797#ifdef MS_WINDOWS
7798 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007799 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007801 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007802 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 if (res < 0)
7804 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007805
7806 /* Character files like console cannot be make non-inheritable */
7807 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7808 close(fd2);
7809 return NULL;
7810 }
7811
7812#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7813 Py_BEGIN_ALLOW_THREADS
7814 if (!inheritable)
7815 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7816 else
7817 res = dup2(fd, fd2);
7818 Py_END_ALLOW_THREADS
7819 if (res < 0)
7820 return posix_error();
7821
7822#else
7823
7824#ifdef HAVE_DUP3
7825 if (!inheritable && dup3_works != 0) {
7826 Py_BEGIN_ALLOW_THREADS
7827 res = dup3(fd, fd2, O_CLOEXEC);
7828 Py_END_ALLOW_THREADS
7829 if (res < 0) {
7830 if (dup3_works == -1)
7831 dup3_works = (errno != ENOSYS);
7832 if (dup3_works)
7833 return posix_error();
7834 }
7835 }
7836
7837 if (inheritable || dup3_works == 0)
7838 {
7839#endif
7840 Py_BEGIN_ALLOW_THREADS
7841 res = dup2(fd, fd2);
7842 Py_END_ALLOW_THREADS
7843 if (res < 0)
7844 return posix_error();
7845
7846 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7847 close(fd2);
7848 return NULL;
7849 }
7850#ifdef HAVE_DUP3
7851 }
7852#endif
7853
7854#endif
7855
Larry Hastings2f936352014-08-05 14:04:04 +10007856 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007857}
7858
Larry Hastings2f936352014-08-05 14:04:04 +10007859
Ross Lagerwall7807c352011-03-17 20:20:30 +02007860#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007861/*[clinic input]
7862os.lockf
7863
7864 fd: int
7865 An open file descriptor.
7866 command: int
7867 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7868 length: Py_off_t
7869 The number of bytes to lock, starting at the current position.
7870 /
7871
7872Apply, test or remove a POSIX lock on an open file descriptor.
7873
7874[clinic start generated code]*/
7875
Larry Hastings2f936352014-08-05 14:04:04 +10007876static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007877os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7878/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007879{
7880 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007881
7882 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007883 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007884 Py_END_ALLOW_THREADS
7885
7886 if (res < 0)
7887 return posix_error();
7888
7889 Py_RETURN_NONE;
7890}
Larry Hastings2f936352014-08-05 14:04:04 +10007891#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007893
Larry Hastings2f936352014-08-05 14:04:04 +10007894/*[clinic input]
7895os.lseek -> Py_off_t
7896
7897 fd: int
7898 position: Py_off_t
7899 how: int
7900 /
7901
7902Set the position of a file descriptor. Return the new position.
7903
7904Return the new cursor position in number of bytes
7905relative to the beginning of the file.
7906[clinic start generated code]*/
7907
Larry Hastings2f936352014-08-05 14:04:04 +10007908static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007909os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7910/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007911{
7912 Py_off_t result;
7913
Guido van Rossum687dd131993-05-17 08:34:16 +00007914#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7916 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007917 case 0: how = SEEK_SET; break;
7918 case 1: how = SEEK_CUR; break;
7919 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007920 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007921#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007922
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007924 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007925
Victor Stinner8c62be82010-05-06 00:08:46 +00007926 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007927 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007928#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007929 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007930#else
Larry Hastings2f936352014-08-05 14:04:04 +10007931 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007932#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007933 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007935 if (result < 0)
7936 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007937
Larry Hastings2f936352014-08-05 14:04:04 +10007938 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007939}
7940
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007941
Larry Hastings2f936352014-08-05 14:04:04 +10007942/*[clinic input]
7943os.read
7944 fd: int
7945 length: Py_ssize_t
7946 /
7947
7948Read from a file descriptor. Returns a bytes object.
7949[clinic start generated code]*/
7950
Larry Hastings2f936352014-08-05 14:04:04 +10007951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007952os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7953/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007954{
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 Py_ssize_t n;
7956 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007957
7958 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007959 errno = EINVAL;
7960 return posix_error();
7961 }
Larry Hastings2f936352014-08-05 14:04:04 +10007962
7963#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007964 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007965 if (length > INT_MAX)
7966 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007967#endif
7968
7969 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 if (buffer == NULL)
7971 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007972
Victor Stinner66aab0c2015-03-19 22:53:20 +01007973 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7974 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007976 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 }
Larry Hastings2f936352014-08-05 14:04:04 +10007978
7979 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007981
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007983}
7984
Ross Lagerwall7807c352011-03-17 20:20:30 +02007985#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7986 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007987static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007988iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007989{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007990 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007991 Py_ssize_t blen, total = 0;
7992
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007993 *iov = PyMem_New(struct iovec, cnt);
7994 if (*iov == NULL) {
7995 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007996 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007997 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007998
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007999 *buf = PyMem_New(Py_buffer, cnt);
8000 if (*buf == NULL) {
8001 PyMem_Del(*iov);
8002 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008003 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008004 }
8005
8006 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008007 PyObject *item = PySequence_GetItem(seq, i);
8008 if (item == NULL)
8009 goto fail;
8010 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8011 Py_DECREF(item);
8012 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008013 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008014 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008015 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008016 blen = (*buf)[i].len;
8017 (*iov)[i].iov_len = blen;
8018 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008019 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008020 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008021
8022fail:
8023 PyMem_Del(*iov);
8024 for (j = 0; j < i; j++) {
8025 PyBuffer_Release(&(*buf)[j]);
8026 }
8027 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008028 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008029}
8030
8031static void
8032iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8033{
8034 int i;
8035 PyMem_Del(iov);
8036 for (i = 0; i < cnt; i++) {
8037 PyBuffer_Release(&buf[i]);
8038 }
8039 PyMem_Del(buf);
8040}
8041#endif
8042
Larry Hastings2f936352014-08-05 14:04:04 +10008043
Ross Lagerwall7807c352011-03-17 20:20:30 +02008044#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008045/*[clinic input]
8046os.readv -> Py_ssize_t
8047
8048 fd: int
8049 buffers: object
8050 /
8051
8052Read from a file descriptor fd into an iterable of buffers.
8053
8054The buffers should be mutable buffers accepting bytes.
8055readv will transfer data into each buffer until it is full
8056and then move on to the next buffer in the sequence to hold
8057the rest of the data.
8058
8059readv returns the total number of bytes read,
8060which may be less than the total capacity of all the buffers.
8061[clinic start generated code]*/
8062
Larry Hastings2f936352014-08-05 14:04:04 +10008063static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008064os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8065/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008066{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008067 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008068 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008069 struct iovec *iov;
8070 Py_buffer *buf;
8071
Larry Hastings2f936352014-08-05 14:04:04 +10008072 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008073 PyErr_SetString(PyExc_TypeError,
8074 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008075 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008076 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008077
Larry Hastings2f936352014-08-05 14:04:04 +10008078 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008079 if (cnt < 0)
8080 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008081
8082 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8083 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008084
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008085 do {
8086 Py_BEGIN_ALLOW_THREADS
8087 n = readv(fd, iov, cnt);
8088 Py_END_ALLOW_THREADS
8089 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008090
8091 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008092 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008093 if (!async_err)
8094 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008095 return -1;
8096 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008097
Larry Hastings2f936352014-08-05 14:04:04 +10008098 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008099}
Larry Hastings2f936352014-08-05 14:04:04 +10008100#endif /* HAVE_READV */
8101
Ross Lagerwall7807c352011-03-17 20:20:30 +02008102
8103#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008104/*[clinic input]
8105# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8106os.pread
8107
8108 fd: int
8109 length: int
8110 offset: Py_off_t
8111 /
8112
8113Read a number of bytes from a file descriptor starting at a particular offset.
8114
8115Read length bytes from file descriptor fd, starting at offset bytes from
8116the beginning of the file. The file offset remains unchanged.
8117[clinic start generated code]*/
8118
Larry Hastings2f936352014-08-05 14:04:04 +10008119static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008120os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8121/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008122{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008123 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008124 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008126
Larry Hastings2f936352014-08-05 14:04:04 +10008127 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008128 errno = EINVAL;
8129 return posix_error();
8130 }
Larry Hastings2f936352014-08-05 14:04:04 +10008131 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008132 if (buffer == NULL)
8133 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008134
8135 do {
8136 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008137 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008138 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008139 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008140 Py_END_ALLOW_THREADS
8141 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8142
Ross Lagerwall7807c352011-03-17 20:20:30 +02008143 if (n < 0) {
8144 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008145 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008146 }
Larry Hastings2f936352014-08-05 14:04:04 +10008147 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148 _PyBytes_Resize(&buffer, n);
8149 return buffer;
8150}
Larry Hastings2f936352014-08-05 14:04:04 +10008151#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008152
Larry Hastings2f936352014-08-05 14:04:04 +10008153
8154/*[clinic input]
8155os.write -> Py_ssize_t
8156
8157 fd: int
8158 data: Py_buffer
8159 /
8160
8161Write a bytes object to a file descriptor.
8162[clinic start generated code]*/
8163
Larry Hastings2f936352014-08-05 14:04:04 +10008164static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008165os_write_impl(PyObject *module, int fd, Py_buffer *data)
8166/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008167{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008168 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169}
8170
8171#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008172PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008173"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008174sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008175 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008176Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008177
Larry Hastings2f936352014-08-05 14:04:04 +10008178/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008179static PyObject *
8180posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8181{
8182 int in, out;
8183 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008184 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008185 off_t offset;
8186
8187#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8188#ifndef __APPLE__
8189 Py_ssize_t len;
8190#endif
8191 PyObject *headers = NULL, *trailers = NULL;
8192 Py_buffer *hbuf, *tbuf;
8193 off_t sbytes;
8194 struct sf_hdtr sf;
8195 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008196 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008197 static char *keywords[] = {"out", "in",
8198 "offset", "count",
8199 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008200
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008201 sf.headers = NULL;
8202 sf.trailers = NULL;
8203
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008204#ifdef __APPLE__
8205 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008206 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008207#else
8208 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008209 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008210#endif
8211 &headers, &trailers, &flags))
8212 return NULL;
8213 if (headers != NULL) {
8214 if (!PySequence_Check(headers)) {
8215 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008216 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008217 return NULL;
8218 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008219 Py_ssize_t i = PySequence_Size(headers);
8220 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008221 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008222 if (i > INT_MAX) {
8223 PyErr_SetString(PyExc_OverflowError,
8224 "sendfile() header is too large");
8225 return NULL;
8226 }
8227 if (i > 0) {
8228 sf.hdr_cnt = (int)i;
8229 i = iov_setup(&(sf.headers), &hbuf,
8230 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8231 if (i < 0)
8232 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008233#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008234 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008235#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008236 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008237 }
8238 }
8239 if (trailers != NULL) {
8240 if (!PySequence_Check(trailers)) {
8241 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008242 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008243 return NULL;
8244 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008245 Py_ssize_t i = PySequence_Size(trailers);
8246 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008248 if (i > INT_MAX) {
8249 PyErr_SetString(PyExc_OverflowError,
8250 "sendfile() trailer is too large");
8251 return NULL;
8252 }
8253 if (i > 0) {
8254 sf.trl_cnt = (int)i;
8255 i = iov_setup(&(sf.trailers), &tbuf,
8256 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8257 if (i < 0)
8258 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008259#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008260 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008261#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008262 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008263 }
8264 }
8265
Steve Dower8fc89802015-04-12 00:26:27 -04008266 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008267 do {
8268 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008269#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008270 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008271#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008272 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008273#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008274 Py_END_ALLOW_THREADS
8275 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008276 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008277
8278 if (sf.headers != NULL)
8279 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8280 if (sf.trailers != NULL)
8281 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8282
8283 if (ret < 0) {
8284 if ((errno == EAGAIN) || (errno == EBUSY)) {
8285 if (sbytes != 0) {
8286 // some data has been sent
8287 goto done;
8288 }
8289 else {
8290 // no data has been sent; upper application is supposed
8291 // to retry on EAGAIN or EBUSY
8292 return posix_error();
8293 }
8294 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008295 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008296 }
8297 goto done;
8298
8299done:
8300 #if !defined(HAVE_LARGEFILE_SUPPORT)
8301 return Py_BuildValue("l", sbytes);
8302 #else
8303 return Py_BuildValue("L", sbytes);
8304 #endif
8305
8306#else
8307 Py_ssize_t count;
8308 PyObject *offobj;
8309 static char *keywords[] = {"out", "in",
8310 "offset", "count", NULL};
8311 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8312 keywords, &out, &in, &offobj, &count))
8313 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008314#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008315 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008316 do {
8317 Py_BEGIN_ALLOW_THREADS
8318 ret = sendfile(out, in, NULL, count);
8319 Py_END_ALLOW_THREADS
8320 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008323 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008324 }
8325#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008326 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008327 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008328
8329 do {
8330 Py_BEGIN_ALLOW_THREADS
8331 ret = sendfile(out, in, &offset, count);
8332 Py_END_ALLOW_THREADS
8333 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008334 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008335 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008336 return Py_BuildValue("n", ret);
8337#endif
8338}
Larry Hastings2f936352014-08-05 14:04:04 +10008339#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008340
Larry Hastings2f936352014-08-05 14:04:04 +10008341
8342/*[clinic input]
8343os.fstat
8344
8345 fd : int
8346
8347Perform a stat system call on the given file descriptor.
8348
8349Like stat(), but for an open file descriptor.
8350Equivalent to os.stat(fd).
8351[clinic start generated code]*/
8352
Larry Hastings2f936352014-08-05 14:04:04 +10008353static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008354os_fstat_impl(PyObject *module, int fd)
8355/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008356{
Victor Stinner8c62be82010-05-06 00:08:46 +00008357 STRUCT_STAT st;
8358 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008359 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008360
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008361 do {
8362 Py_BEGIN_ALLOW_THREADS
8363 res = FSTAT(fd, &st);
8364 Py_END_ALLOW_THREADS
8365 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008367#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008368 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008369#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008370 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008371#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 }
Tim Peters5aa91602002-01-30 05:46:57 +00008373
Victor Stinner4195b5c2012-02-08 23:03:19 +01008374 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008375}
8376
Larry Hastings2f936352014-08-05 14:04:04 +10008377
8378/*[clinic input]
8379os.isatty -> bool
8380 fd: int
8381 /
8382
8383Return True if the fd is connected to a terminal.
8384
8385Return True if the file descriptor is an open file descriptor
8386connected to the slave end of a terminal.
8387[clinic start generated code]*/
8388
Larry Hastings2f936352014-08-05 14:04:04 +10008389static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008390os_isatty_impl(PyObject *module, int fd)
8391/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008392{
Steve Dower8fc89802015-04-12 00:26:27 -04008393 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008394 _Py_BEGIN_SUPPRESS_IPH
8395 return_value = isatty(fd);
8396 _Py_END_SUPPRESS_IPH
8397 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008398}
8399
8400
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008401#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008402/*[clinic input]
8403os.pipe
8404
8405Create a pipe.
8406
8407Returns a tuple of two file descriptors:
8408 (read_fd, write_fd)
8409[clinic start generated code]*/
8410
Larry Hastings2f936352014-08-05 14:04:04 +10008411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008412os_pipe_impl(PyObject *module)
8413/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008414{
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008416#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008417 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008418 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008420#else
8421 int res;
8422#endif
8423
8424#ifdef MS_WINDOWS
8425 attr.nLength = sizeof(attr);
8426 attr.lpSecurityDescriptor = NULL;
8427 attr.bInheritHandle = FALSE;
8428
8429 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008430 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008431 ok = CreatePipe(&read, &write, &attr, 0);
8432 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008433 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8434 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008435 if (fds[0] == -1 || fds[1] == -1) {
8436 CloseHandle(read);
8437 CloseHandle(write);
8438 ok = 0;
8439 }
8440 }
Steve Dowerc3630612016-11-19 18:41:16 -08008441 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008442 Py_END_ALLOW_THREADS
8443
Victor Stinner8c62be82010-05-06 00:08:46 +00008444 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008445 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008446#else
8447
8448#ifdef HAVE_PIPE2
8449 Py_BEGIN_ALLOW_THREADS
8450 res = pipe2(fds, O_CLOEXEC);
8451 Py_END_ALLOW_THREADS
8452
8453 if (res != 0 && errno == ENOSYS)
8454 {
8455#endif
8456 Py_BEGIN_ALLOW_THREADS
8457 res = pipe(fds);
8458 Py_END_ALLOW_THREADS
8459
8460 if (res == 0) {
8461 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8462 close(fds[0]);
8463 close(fds[1]);
8464 return NULL;
8465 }
8466 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8467 close(fds[0]);
8468 close(fds[1]);
8469 return NULL;
8470 }
8471 }
8472#ifdef HAVE_PIPE2
8473 }
8474#endif
8475
8476 if (res != 0)
8477 return PyErr_SetFromErrno(PyExc_OSError);
8478#endif /* !MS_WINDOWS */
8479 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008480}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008481#endif /* HAVE_PIPE */
8482
Larry Hastings2f936352014-08-05 14:04:04 +10008483
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008484#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008485/*[clinic input]
8486os.pipe2
8487
8488 flags: int
8489 /
8490
8491Create a pipe with flags set atomically.
8492
8493Returns a tuple of two file descriptors:
8494 (read_fd, write_fd)
8495
8496flags can be constructed by ORing together one or more of these values:
8497O_NONBLOCK, O_CLOEXEC.
8498[clinic start generated code]*/
8499
Larry Hastings2f936352014-08-05 14:04:04 +10008500static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008501os_pipe2_impl(PyObject *module, int flags)
8502/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008503{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008504 int fds[2];
8505 int res;
8506
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008507 res = pipe2(fds, flags);
8508 if (res != 0)
8509 return posix_error();
8510 return Py_BuildValue("(ii)", fds[0], fds[1]);
8511}
8512#endif /* HAVE_PIPE2 */
8513
Larry Hastings2f936352014-08-05 14:04:04 +10008514
Ross Lagerwall7807c352011-03-17 20:20:30 +02008515#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008516/*[clinic input]
8517os.writev -> Py_ssize_t
8518 fd: int
8519 buffers: object
8520 /
8521
8522Iterate over buffers, and write the contents of each to a file descriptor.
8523
8524Returns the total number of bytes written.
8525buffers must be a sequence of bytes-like objects.
8526[clinic start generated code]*/
8527
Larry Hastings2f936352014-08-05 14:04:04 +10008528static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008529os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8530/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008531{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008532 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008533 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008534 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008535 struct iovec *iov;
8536 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008537
8538 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008539 PyErr_SetString(PyExc_TypeError,
8540 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008541 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008542 }
Larry Hastings2f936352014-08-05 14:04:04 +10008543 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008544 if (cnt < 0)
8545 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008546
Larry Hastings2f936352014-08-05 14:04:04 +10008547 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8548 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008549 }
8550
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008551 do {
8552 Py_BEGIN_ALLOW_THREADS
8553 result = writev(fd, iov, cnt);
8554 Py_END_ALLOW_THREADS
8555 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008556
8557 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008558 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008559 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008560
Georg Brandl306336b2012-06-24 12:55:33 +02008561 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008562}
Larry Hastings2f936352014-08-05 14:04:04 +10008563#endif /* HAVE_WRITEV */
8564
8565
8566#ifdef HAVE_PWRITE
8567/*[clinic input]
8568os.pwrite -> Py_ssize_t
8569
8570 fd: int
8571 buffer: Py_buffer
8572 offset: Py_off_t
8573 /
8574
8575Write bytes to a file descriptor starting at a particular offset.
8576
8577Write buffer to fd, starting at offset bytes from the beginning of
8578the file. Returns the number of bytes writte. Does not change the
8579current file offset.
8580[clinic start generated code]*/
8581
Larry Hastings2f936352014-08-05 14:04:04 +10008582static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008583os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8584/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008585{
8586 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008587 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008588
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008589 do {
8590 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008591 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008592 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008593 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008594 Py_END_ALLOW_THREADS
8595 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008596
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008597 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008598 posix_error();
8599 return size;
8600}
8601#endif /* HAVE_PWRITE */
8602
8603
8604#ifdef HAVE_MKFIFO
8605/*[clinic input]
8606os.mkfifo
8607
8608 path: path_t
8609 mode: int=0o666
8610 *
8611 dir_fd: dir_fd(requires='mkfifoat')=None
8612
8613Create a "fifo" (a POSIX named pipe).
8614
8615If dir_fd is not None, it should be a file descriptor open to a directory,
8616 and path should be relative; path will then be relative to that directory.
8617dir_fd may not be implemented on your platform.
8618 If it is unavailable, using it will raise a NotImplementedError.
8619[clinic start generated code]*/
8620
Larry Hastings2f936352014-08-05 14:04:04 +10008621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008622os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8623/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008624{
8625 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008626 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008627
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008628 do {
8629 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008630#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008631 if (dir_fd != DEFAULT_DIR_FD)
8632 result = mkfifoat(dir_fd, path->narrow, mode);
8633 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008634#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 result = mkfifo(path->narrow, mode);
8636 Py_END_ALLOW_THREADS
8637 } while (result != 0 && errno == EINTR &&
8638 !(async_err = PyErr_CheckSignals()));
8639 if (result != 0)
8640 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008641
8642 Py_RETURN_NONE;
8643}
8644#endif /* HAVE_MKFIFO */
8645
8646
8647#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8648/*[clinic input]
8649os.mknod
8650
8651 path: path_t
8652 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008653 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008654 *
8655 dir_fd: dir_fd(requires='mknodat')=None
8656
8657Create a node in the file system.
8658
8659Create a node in the file system (file, device special file or named pipe)
8660at path. mode specifies both the permissions to use and the
8661type of node to be created, being combined (bitwise OR) with one of
8662S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8663device defines the newly created device special file (probably using
8664os.makedev()). Otherwise device is ignored.
8665
8666If dir_fd is not None, it should be a file descriptor open to a directory,
8667 and path should be relative; path will then be relative to that directory.
8668dir_fd may not be implemented on your platform.
8669 If it is unavailable, using it will raise a NotImplementedError.
8670[clinic start generated code]*/
8671
Larry Hastings2f936352014-08-05 14:04:04 +10008672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008673os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008674 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008675/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008676{
8677 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008678 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008679
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 do {
8681 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008682#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008683 if (dir_fd != DEFAULT_DIR_FD)
8684 result = mknodat(dir_fd, path->narrow, mode, device);
8685 else
Larry Hastings2f936352014-08-05 14:04:04 +10008686#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008687 result = mknod(path->narrow, mode, device);
8688 Py_END_ALLOW_THREADS
8689 } while (result != 0 && errno == EINTR &&
8690 !(async_err = PyErr_CheckSignals()));
8691 if (result != 0)
8692 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008693
8694 Py_RETURN_NONE;
8695}
8696#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8697
8698
8699#ifdef HAVE_DEVICE_MACROS
8700/*[clinic input]
8701os.major -> unsigned_int
8702
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008703 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008704 /
8705
8706Extracts a device major number from a raw device number.
8707[clinic start generated code]*/
8708
Larry Hastings2f936352014-08-05 14:04:04 +10008709static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008710os_major_impl(PyObject *module, dev_t device)
8711/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008712{
8713 return major(device);
8714}
8715
8716
8717/*[clinic input]
8718os.minor -> unsigned_int
8719
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008720 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008721 /
8722
8723Extracts a device minor number from a raw device number.
8724[clinic start generated code]*/
8725
Larry Hastings2f936352014-08-05 14:04:04 +10008726static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008727os_minor_impl(PyObject *module, dev_t device)
8728/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008729{
8730 return minor(device);
8731}
8732
8733
8734/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008735os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008736
8737 major: int
8738 minor: int
8739 /
8740
8741Composes a raw device number from the major and minor device numbers.
8742[clinic start generated code]*/
8743
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008744static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008745os_makedev_impl(PyObject *module, int major, int minor)
8746/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008747{
8748 return makedev(major, minor);
8749}
8750#endif /* HAVE_DEVICE_MACROS */
8751
8752
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008753#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008754/*[clinic input]
8755os.ftruncate
8756
8757 fd: int
8758 length: Py_off_t
8759 /
8760
8761Truncate a file, specified by file descriptor, to a specific length.
8762[clinic start generated code]*/
8763
Larry Hastings2f936352014-08-05 14:04:04 +10008764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008765os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8766/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008767{
8768 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008769 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008770
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008771 do {
8772 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008773 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008774#ifdef MS_WINDOWS
8775 result = _chsize_s(fd, length);
8776#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008777 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008778#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008779 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008780 Py_END_ALLOW_THREADS
8781 } while (result != 0 && errno == EINTR &&
8782 !(async_err = PyErr_CheckSignals()));
8783 if (result != 0)
8784 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008785 Py_RETURN_NONE;
8786}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008787#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008788
8789
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008790#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008791/*[clinic input]
8792os.truncate
8793 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8794 length: Py_off_t
8795
8796Truncate a file, specified by path, to a specific length.
8797
8798On some platforms, path may also be specified as an open file descriptor.
8799 If this functionality is unavailable, using it raises an exception.
8800[clinic start generated code]*/
8801
Larry Hastings2f936352014-08-05 14:04:04 +10008802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008803os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8804/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008805{
8806 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008807#ifdef MS_WINDOWS
8808 int fd;
8809#endif
8810
8811 if (path->fd != -1)
8812 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008813
8814 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008815 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008816#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008817 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008818 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008819 result = -1;
8820 else {
8821 result = _chsize_s(fd, length);
8822 close(fd);
8823 if (result < 0)
8824 errno = result;
8825 }
8826#else
8827 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008828#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008829 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008830 Py_END_ALLOW_THREADS
8831 if (result < 0)
8832 return path_error(path);
8833
8834 Py_RETURN_NONE;
8835}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008836#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008837
Ross Lagerwall7807c352011-03-17 20:20:30 +02008838
Victor Stinnerd6b17692014-09-30 12:20:05 +02008839/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8840 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8841 defined, which is the case in Python on AIX. AIX bug report:
8842 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8843#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8844# define POSIX_FADVISE_AIX_BUG
8845#endif
8846
Victor Stinnerec39e262014-09-30 12:35:58 +02008847
Victor Stinnerd6b17692014-09-30 12:20:05 +02008848#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008849/*[clinic input]
8850os.posix_fallocate
8851
8852 fd: int
8853 offset: Py_off_t
8854 length: Py_off_t
8855 /
8856
8857Ensure a file has allocated at least a particular number of bytes on disk.
8858
8859Ensure that the file specified by fd encompasses a range of bytes
8860starting at offset bytes from the beginning and continuing for length bytes.
8861[clinic start generated code]*/
8862
Larry Hastings2f936352014-08-05 14:04:04 +10008863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008864os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008865 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008866/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008867{
8868 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008869 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008870
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008871 do {
8872 Py_BEGIN_ALLOW_THREADS
8873 result = posix_fallocate(fd, offset, length);
8874 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008875 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8876
8877 if (result == 0)
8878 Py_RETURN_NONE;
8879
8880 if (async_err)
8881 return NULL;
8882
8883 errno = result;
8884 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008885}
Victor Stinnerec39e262014-09-30 12:35:58 +02008886#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008887
Ross Lagerwall7807c352011-03-17 20:20:30 +02008888
Victor Stinnerd6b17692014-09-30 12:20:05 +02008889#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008890/*[clinic input]
8891os.posix_fadvise
8892
8893 fd: int
8894 offset: Py_off_t
8895 length: Py_off_t
8896 advice: int
8897 /
8898
8899Announce an intention to access data in a specific pattern.
8900
8901Announce an intention to access data in a specific pattern, thus allowing
8902the kernel to make optimizations.
8903The advice applies to the region of the file specified by fd starting at
8904offset and continuing for length bytes.
8905advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8906POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8907POSIX_FADV_DONTNEED.
8908[clinic start generated code]*/
8909
Larry Hastings2f936352014-08-05 14:04:04 +10008910static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008911os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008912 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008913/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008914{
8915 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008916 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008917
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008918 do {
8919 Py_BEGIN_ALLOW_THREADS
8920 result = posix_fadvise(fd, offset, length, advice);
8921 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008922 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8923
8924 if (result == 0)
8925 Py_RETURN_NONE;
8926
8927 if (async_err)
8928 return NULL;
8929
8930 errno = result;
8931 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008932}
Victor Stinnerec39e262014-09-30 12:35:58 +02008933#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008934
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008935#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008936
Fred Drake762e2061999-08-26 17:23:54 +00008937/* Save putenv() parameters as values here, so we can collect them when they
8938 * get re-set with another call for the same key. */
8939static PyObject *posix_putenv_garbage;
8940
Larry Hastings2f936352014-08-05 14:04:04 +10008941static void
8942posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008943{
Larry Hastings2f936352014-08-05 14:04:04 +10008944 /* Install the first arg and newstr in posix_putenv_garbage;
8945 * this will cause previous value to be collected. This has to
8946 * happen after the real putenv() call because the old value
8947 * was still accessible until then. */
8948 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8949 /* really not much we can do; just leak */
8950 PyErr_Clear();
8951 else
8952 Py_DECREF(value);
8953}
8954
8955
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008956#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008957/*[clinic input]
8958os.putenv
8959
8960 name: unicode
8961 value: unicode
8962 /
8963
8964Change or add an environment variable.
8965[clinic start generated code]*/
8966
Larry Hastings2f936352014-08-05 14:04:04 +10008967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008968os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8969/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008970{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008971 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008972 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10008973
Serhiy Storchaka77703942017-06-25 07:33:01 +03008974 /* Search from index 1 because on Windows starting '=' is allowed for
8975 defining hidden environment variables. */
8976 if (PyUnicode_GET_LENGTH(name) == 0 ||
8977 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
8978 {
8979 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
8980 return NULL;
8981 }
Larry Hastings2f936352014-08-05 14:04:04 +10008982 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8983 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10008984 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008985 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008986
8987 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
8988 if (env == NULL)
8989 goto error;
8990 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01008991 PyErr_Format(PyExc_ValueError,
8992 "the environment variable is longer than %u characters",
8993 _MAX_ENV);
8994 goto error;
8995 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008996 if (wcslen(env) != (size_t)size) {
8997 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02008998 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008999 }
9000
Larry Hastings2f936352014-08-05 14:04:04 +10009001 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009002 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009003 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009005
Larry Hastings2f936352014-08-05 14:04:04 +10009006 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009007 Py_RETURN_NONE;
9008
9009error:
Larry Hastings2f936352014-08-05 14:04:04 +10009010 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009011 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009012}
Larry Hastings2f936352014-08-05 14:04:04 +10009013#else /* MS_WINDOWS */
9014/*[clinic input]
9015os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009016
Larry Hastings2f936352014-08-05 14:04:04 +10009017 name: FSConverter
9018 value: FSConverter
9019 /
9020
9021Change or add an environment variable.
9022[clinic start generated code]*/
9023
Larry Hastings2f936352014-08-05 14:04:04 +10009024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009025os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9026/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009027{
9028 PyObject *bytes = NULL;
9029 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009030 const char *name_string = PyBytes_AS_STRING(name);
9031 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009032
Serhiy Storchaka77703942017-06-25 07:33:01 +03009033 if (strchr(name_string, '=') != NULL) {
9034 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9035 return NULL;
9036 }
Larry Hastings2f936352014-08-05 14:04:04 +10009037 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9038 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009039 return NULL;
9040 }
9041
9042 env = PyBytes_AS_STRING(bytes);
9043 if (putenv(env)) {
9044 Py_DECREF(bytes);
9045 return posix_error();
9046 }
9047
9048 posix_putenv_garbage_setitem(name, bytes);
9049 Py_RETURN_NONE;
9050}
9051#endif /* MS_WINDOWS */
9052#endif /* HAVE_PUTENV */
9053
9054
9055#ifdef HAVE_UNSETENV
9056/*[clinic input]
9057os.unsetenv
9058 name: FSConverter
9059 /
9060
9061Delete an environment variable.
9062[clinic start generated code]*/
9063
Larry Hastings2f936352014-08-05 14:04:04 +10009064static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009065os_unsetenv_impl(PyObject *module, PyObject *name)
9066/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009067{
Victor Stinner984890f2011-11-24 13:53:38 +01009068#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009069 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009070#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009071
Victor Stinner984890f2011-11-24 13:53:38 +01009072#ifdef HAVE_BROKEN_UNSETENV
9073 unsetenv(PyBytes_AS_STRING(name));
9074#else
Victor Stinner65170952011-11-22 22:16:17 +01009075 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009076 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009077 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009078#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009079
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 /* Remove the key from posix_putenv_garbage;
9081 * this will cause it to be collected. This has to
9082 * happen after the real unsetenv() call because the
9083 * old value was still accessible until then.
9084 */
Victor Stinner65170952011-11-22 22:16:17 +01009085 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 /* really not much we can do; just leak */
9087 PyErr_Clear();
9088 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009089 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009090}
Larry Hastings2f936352014-08-05 14:04:04 +10009091#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009092
Larry Hastings2f936352014-08-05 14:04:04 +10009093
9094/*[clinic input]
9095os.strerror
9096
9097 code: int
9098 /
9099
9100Translate an error code to a message string.
9101[clinic start generated code]*/
9102
Larry Hastings2f936352014-08-05 14:04:04 +10009103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009104os_strerror_impl(PyObject *module, int code)
9105/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009106{
9107 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 if (message == NULL) {
9109 PyErr_SetString(PyExc_ValueError,
9110 "strerror() argument out of range");
9111 return NULL;
9112 }
Victor Stinner1b579672011-12-17 05:47:23 +01009113 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009114}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009115
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009116
Guido van Rossumc9641791998-08-04 15:26:23 +00009117#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009118#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009119/*[clinic input]
9120os.WCOREDUMP -> bool
9121
9122 status: int
9123 /
9124
9125Return True if the process returning status was dumped to a core file.
9126[clinic start generated code]*/
9127
Larry Hastings2f936352014-08-05 14:04:04 +10009128static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009129os_WCOREDUMP_impl(PyObject *module, int status)
9130/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009131{
9132 WAIT_TYPE wait_status;
9133 WAIT_STATUS_INT(wait_status) = status;
9134 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009135}
9136#endif /* WCOREDUMP */
9137
Larry Hastings2f936352014-08-05 14:04:04 +10009138
Fred Drake106c1a02002-04-23 15:58:02 +00009139#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009140/*[clinic input]
9141os.WIFCONTINUED -> bool
9142
9143 status: int
9144
9145Return True if a particular process was continued from a job control stop.
9146
9147Return True if the process returning status was continued from a
9148job control stop.
9149[clinic start generated code]*/
9150
Larry Hastings2f936352014-08-05 14:04:04 +10009151static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009152os_WIFCONTINUED_impl(PyObject *module, int status)
9153/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009154{
9155 WAIT_TYPE wait_status;
9156 WAIT_STATUS_INT(wait_status) = status;
9157 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009158}
9159#endif /* WIFCONTINUED */
9160
Larry Hastings2f936352014-08-05 14:04:04 +10009161
Guido van Rossumc9641791998-08-04 15:26:23 +00009162#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009163/*[clinic input]
9164os.WIFSTOPPED -> bool
9165
9166 status: int
9167
9168Return True if the process returning status was stopped.
9169[clinic start generated code]*/
9170
Larry Hastings2f936352014-08-05 14:04:04 +10009171static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009172os_WIFSTOPPED_impl(PyObject *module, int status)
9173/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009174{
9175 WAIT_TYPE wait_status;
9176 WAIT_STATUS_INT(wait_status) = status;
9177 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009178}
9179#endif /* WIFSTOPPED */
9180
Larry Hastings2f936352014-08-05 14:04:04 +10009181
Guido van Rossumc9641791998-08-04 15:26:23 +00009182#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009183/*[clinic input]
9184os.WIFSIGNALED -> bool
9185
9186 status: int
9187
9188Return True if the process returning status was terminated by a signal.
9189[clinic start generated code]*/
9190
Larry Hastings2f936352014-08-05 14:04:04 +10009191static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009192os_WIFSIGNALED_impl(PyObject *module, int status)
9193/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009194{
9195 WAIT_TYPE wait_status;
9196 WAIT_STATUS_INT(wait_status) = status;
9197 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009198}
9199#endif /* WIFSIGNALED */
9200
Larry Hastings2f936352014-08-05 14:04:04 +10009201
Guido van Rossumc9641791998-08-04 15:26:23 +00009202#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009203/*[clinic input]
9204os.WIFEXITED -> bool
9205
9206 status: int
9207
9208Return True if the process returning status exited via the exit() system call.
9209[clinic start generated code]*/
9210
Larry Hastings2f936352014-08-05 14:04:04 +10009211static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009212os_WIFEXITED_impl(PyObject *module, int status)
9213/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009214{
9215 WAIT_TYPE wait_status;
9216 WAIT_STATUS_INT(wait_status) = status;
9217 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009218}
9219#endif /* WIFEXITED */
9220
Larry Hastings2f936352014-08-05 14:04:04 +10009221
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009222#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009223/*[clinic input]
9224os.WEXITSTATUS -> int
9225
9226 status: int
9227
9228Return the process return code from status.
9229[clinic start generated code]*/
9230
Larry Hastings2f936352014-08-05 14:04:04 +10009231static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009232os_WEXITSTATUS_impl(PyObject *module, int status)
9233/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009234{
9235 WAIT_TYPE wait_status;
9236 WAIT_STATUS_INT(wait_status) = status;
9237 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009238}
9239#endif /* WEXITSTATUS */
9240
Larry Hastings2f936352014-08-05 14:04:04 +10009241
Guido van Rossumc9641791998-08-04 15:26:23 +00009242#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009243/*[clinic input]
9244os.WTERMSIG -> int
9245
9246 status: int
9247
9248Return the signal that terminated the process that provided the status value.
9249[clinic start generated code]*/
9250
Larry Hastings2f936352014-08-05 14:04:04 +10009251static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009252os_WTERMSIG_impl(PyObject *module, int status)
9253/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009254{
9255 WAIT_TYPE wait_status;
9256 WAIT_STATUS_INT(wait_status) = status;
9257 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009258}
9259#endif /* WTERMSIG */
9260
Larry Hastings2f936352014-08-05 14:04:04 +10009261
Guido van Rossumc9641791998-08-04 15:26:23 +00009262#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009263/*[clinic input]
9264os.WSTOPSIG -> int
9265
9266 status: int
9267
9268Return the signal that stopped the process that provided the status value.
9269[clinic start generated code]*/
9270
Larry Hastings2f936352014-08-05 14:04:04 +10009271static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009272os_WSTOPSIG_impl(PyObject *module, int status)
9273/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009274{
9275 WAIT_TYPE wait_status;
9276 WAIT_STATUS_INT(wait_status) = status;
9277 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009278}
9279#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009280#endif /* HAVE_SYS_WAIT_H */
9281
9282
Thomas Wouters477c8d52006-05-27 19:21:47 +00009283#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009284#ifdef _SCO_DS
9285/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9286 needed definitions in sys/statvfs.h */
9287#define _SVID3
9288#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009289#include <sys/statvfs.h>
9290
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009291static PyObject*
9292_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9294 if (v == NULL)
9295 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009296
9297#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009298 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9299 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9300 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9301 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9302 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9303 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9304 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9305 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9306 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9307 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009308#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9310 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9311 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009312 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009314 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009316 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009318 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009320 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009321 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009322 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9324 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009325#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009326 if (PyErr_Occurred()) {
9327 Py_DECREF(v);
9328 return NULL;
9329 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009330
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009332}
9333
Larry Hastings2f936352014-08-05 14:04:04 +10009334
9335/*[clinic input]
9336os.fstatvfs
9337 fd: int
9338 /
9339
9340Perform an fstatvfs system call on the given fd.
9341
9342Equivalent to statvfs(fd).
9343[clinic start generated code]*/
9344
Larry Hastings2f936352014-08-05 14:04:04 +10009345static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009346os_fstatvfs_impl(PyObject *module, int fd)
9347/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009348{
9349 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009350 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009352
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009353 do {
9354 Py_BEGIN_ALLOW_THREADS
9355 result = fstatvfs(fd, &st);
9356 Py_END_ALLOW_THREADS
9357 } while (result != 0 && errno == EINTR &&
9358 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009359 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009360 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009361
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009363}
Larry Hastings2f936352014-08-05 14:04:04 +10009364#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009365
9366
Thomas Wouters477c8d52006-05-27 19:21:47 +00009367#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009368#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009369/*[clinic input]
9370os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009371
Larry Hastings2f936352014-08-05 14:04:04 +10009372 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9373
9374Perform a statvfs system call on the given path.
9375
9376path may always be specified as a string.
9377On some platforms, path may also be specified as an open file descriptor.
9378 If this functionality is unavailable, using it raises an exception.
9379[clinic start generated code]*/
9380
Larry Hastings2f936352014-08-05 14:04:04 +10009381static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009382os_statvfs_impl(PyObject *module, path_t *path)
9383/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009384{
9385 int result;
9386 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009387
9388 Py_BEGIN_ALLOW_THREADS
9389#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009390 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009391#ifdef __APPLE__
9392 /* handle weak-linking on Mac OS X 10.3 */
9393 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009394 fd_specified("statvfs", path->fd);
9395 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009396 }
9397#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009398 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009399 }
9400 else
9401#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009402 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009403 Py_END_ALLOW_THREADS
9404
9405 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009406 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009407 }
9408
Larry Hastings2f936352014-08-05 14:04:04 +10009409 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009410}
Larry Hastings2f936352014-08-05 14:04:04 +10009411#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9412
Guido van Rossum94f6f721999-01-06 18:42:14 +00009413
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009414#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009415/*[clinic input]
9416os._getdiskusage
9417
9418 path: Py_UNICODE
9419
9420Return disk usage statistics about the given path as a (total, free) tuple.
9421[clinic start generated code]*/
9422
Larry Hastings2f936352014-08-05 14:04:04 +10009423static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009424os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9425/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009426{
9427 BOOL retval;
9428 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009429
9430 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009431 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009432 Py_END_ALLOW_THREADS
9433 if (retval == 0)
9434 return PyErr_SetFromWindowsErr(0);
9435
9436 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9437}
Larry Hastings2f936352014-08-05 14:04:04 +10009438#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009439
9440
Fred Drakec9680921999-12-13 16:37:25 +00009441/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9442 * It maps strings representing configuration variable names to
9443 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009444 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009445 * rarely-used constants. There are three separate tables that use
9446 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009447 *
9448 * This code is always included, even if none of the interfaces that
9449 * need it are included. The #if hackery needed to avoid it would be
9450 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009451 */
9452struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009453 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009454 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009455};
9456
Fred Drake12c6e2d1999-12-14 21:25:03 +00009457static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009458conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009459 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009460{
Christian Heimes217cfd12007-12-02 14:31:20 +00009461 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009462 int value = _PyLong_AsInt(arg);
9463 if (value == -1 && PyErr_Occurred())
9464 return 0;
9465 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009466 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009467 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009468 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009469 /* look up the value in the table using a binary search */
9470 size_t lo = 0;
9471 size_t mid;
9472 size_t hi = tablesize;
9473 int cmp;
9474 const char *confname;
9475 if (!PyUnicode_Check(arg)) {
9476 PyErr_SetString(PyExc_TypeError,
9477 "configuration names must be strings or integers");
9478 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009480 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009481 if (confname == NULL)
9482 return 0;
9483 while (lo < hi) {
9484 mid = (lo + hi) / 2;
9485 cmp = strcmp(confname, table[mid].name);
9486 if (cmp < 0)
9487 hi = mid;
9488 else if (cmp > 0)
9489 lo = mid + 1;
9490 else {
9491 *valuep = table[mid].value;
9492 return 1;
9493 }
9494 }
9495 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9496 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009498}
9499
9500
9501#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9502static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009503#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009505#endif
9506#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009508#endif
Fred Drakec9680921999-12-13 16:37:25 +00009509#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009511#endif
9512#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009514#endif
9515#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009517#endif
9518#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009520#endif
9521#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
9524#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009526#endif
9527#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009529#endif
9530#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009532#endif
9533#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009535#endif
9536#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
9539#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009554#ifdef _PC_ACL_ENABLED
9555 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9556#endif
9557#ifdef _PC_MIN_HOLE_SIZE
9558 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9559#endif
9560#ifdef _PC_ALLOC_SIZE_MIN
9561 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9562#endif
9563#ifdef _PC_REC_INCR_XFER_SIZE
9564 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9565#endif
9566#ifdef _PC_REC_MAX_XFER_SIZE
9567 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9568#endif
9569#ifdef _PC_REC_MIN_XFER_SIZE
9570 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9571#endif
9572#ifdef _PC_REC_XFER_ALIGN
9573 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9574#endif
9575#ifdef _PC_SYMLINK_MAX
9576 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9577#endif
9578#ifdef _PC_XATTR_ENABLED
9579 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9580#endif
9581#ifdef _PC_XATTR_EXISTS
9582 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9583#endif
9584#ifdef _PC_TIMESTAMP_RESOLUTION
9585 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9586#endif
Fred Drakec9680921999-12-13 16:37:25 +00009587};
9588
Fred Drakec9680921999-12-13 16:37:25 +00009589static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009590conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009591{
9592 return conv_confname(arg, valuep, posix_constants_pathconf,
9593 sizeof(posix_constants_pathconf)
9594 / sizeof(struct constdef));
9595}
9596#endif
9597
Larry Hastings2f936352014-08-05 14:04:04 +10009598
Fred Drakec9680921999-12-13 16:37:25 +00009599#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009600/*[clinic input]
9601os.fpathconf -> long
9602
9603 fd: int
9604 name: path_confname
9605 /
9606
9607Return the configuration limit name for the file descriptor fd.
9608
9609If there is no limit, return -1.
9610[clinic start generated code]*/
9611
Larry Hastings2f936352014-08-05 14:04:04 +10009612static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009613os_fpathconf_impl(PyObject *module, int fd, int name)
9614/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009615{
9616 long limit;
9617
9618 errno = 0;
9619 limit = fpathconf(fd, name);
9620 if (limit == -1 && errno != 0)
9621 posix_error();
9622
9623 return limit;
9624}
9625#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009626
9627
9628#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009629/*[clinic input]
9630os.pathconf -> long
9631 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9632 name: path_confname
9633
9634Return the configuration limit name for the file or directory path.
9635
9636If there is no limit, return -1.
9637On some platforms, path may also be specified as an open file descriptor.
9638 If this functionality is unavailable, using it raises an exception.
9639[clinic start generated code]*/
9640
Larry Hastings2f936352014-08-05 14:04:04 +10009641static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009642os_pathconf_impl(PyObject *module, path_t *path, int name)
9643/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009644{
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009646
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009648#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009649 if (path->fd != -1)
9650 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009651 else
9652#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009653 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 if (limit == -1 && errno != 0) {
9655 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009656 /* could be a path or name problem */
9657 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009658 else
Larry Hastings2f936352014-08-05 14:04:04 +10009659 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 }
Larry Hastings2f936352014-08-05 14:04:04 +10009661
9662 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009663}
Larry Hastings2f936352014-08-05 14:04:04 +10009664#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009665
9666#ifdef HAVE_CONFSTR
9667static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009668#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009670#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009671#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009673#endif
9674#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009676#endif
Fred Draked86ed291999-12-15 15:34:33 +00009677#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009679#endif
9680#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009682#endif
9683#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009685#endif
9686#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009688#endif
Fred Drakec9680921999-12-13 16:37:25 +00009689#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
Fred Draked86ed291999-12-15 15:34:33 +00009713#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009715#endif
Fred Drakec9680921999-12-13 16:37:25 +00009716#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
Fred Draked86ed291999-12-15 15:34:33 +00009719#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009721#endif
9722#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
9725#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009727#endif
9728#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009730#endif
Fred Drakec9680921999-12-13 16:37:25 +00009731#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
Fred Draked86ed291999-12-15 15:34:33 +00009779#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009781#endif
9782#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009784#endif
9785#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009787#endif
9788#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009790#endif
9791#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009793#endif
9794#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009796#endif
9797#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
9800#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009802#endif
9803#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009805#endif
9806#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009808#endif
9809#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009811#endif
9812#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009814#endif
9815#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009817#endif
Fred Drakec9680921999-12-13 16:37:25 +00009818};
9819
9820static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009821conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009822{
9823 return conv_confname(arg, valuep, posix_constants_confstr,
9824 sizeof(posix_constants_confstr)
9825 / sizeof(struct constdef));
9826}
9827
Larry Hastings2f936352014-08-05 14:04:04 +10009828
9829/*[clinic input]
9830os.confstr
9831
9832 name: confstr_confname
9833 /
9834
9835Return a string-valued system configuration variable.
9836[clinic start generated code]*/
9837
Larry Hastings2f936352014-08-05 14:04:04 +10009838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009839os_confstr_impl(PyObject *module, int name)
9840/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009841{
9842 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009843 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009844 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009845
Victor Stinnercb043522010-09-10 23:49:04 +00009846 errno = 0;
9847 len = confstr(name, buffer, sizeof(buffer));
9848 if (len == 0) {
9849 if (errno) {
9850 posix_error();
9851 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009852 }
9853 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009854 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009855 }
9856 }
Victor Stinnercb043522010-09-10 23:49:04 +00009857
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009858 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009859 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009860 char *buf = PyMem_Malloc(len);
9861 if (buf == NULL)
9862 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009863 len2 = confstr(name, buf, len);
9864 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009865 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009866 PyMem_Free(buf);
9867 }
9868 else
9869 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009870 return result;
9871}
Larry Hastings2f936352014-08-05 14:04:04 +10009872#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009873
9874
9875#ifdef HAVE_SYSCONF
9876static struct constdef posix_constants_sysconf[] = {
9877#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
Fred Draked86ed291999-12-15 15:34:33 +00009907#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009909#endif
9910#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009912#endif
Fred Drakec9680921999-12-13 16:37:25 +00009913#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
Fred Drakec9680921999-12-13 16:37:25 +00009916#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
Fred Draked86ed291999-12-15 15:34:33 +00009931#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009933#endif
Fred Drakec9680921999-12-13 16:37:25 +00009934#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
Fred Draked86ed291999-12-15 15:34:33 +00009949#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009951#endif
Fred Drakec9680921999-12-13 16:37:25 +00009952#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
Fred Draked86ed291999-12-15 15:34:33 +000010021#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010023#endif
Fred Drakec9680921999-12-13 16:37:25 +000010024#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
Fred Draked86ed291999-12-15 15:34:33 +000010033#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010035#endif
Fred Drakec9680921999-12-13 16:37:25 +000010036#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
Fred Draked86ed291999-12-15 15:34:33 +000010039#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010041#endif
10042#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010044#endif
Fred Drakec9680921999-12-13 16:37:25 +000010045#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
Fred Draked86ed291999-12-15 15:34:33 +000010057#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010059#endif
Fred Drakec9680921999-12-13 16:37:25 +000010060#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
Fred Draked86ed291999-12-15 15:34:33 +000010081#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010083#endif
Fred Drakec9680921999-12-13 16:37:25 +000010084#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
Fred Draked86ed291999-12-15 15:34:33 +000010090#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010092#endif
Fred Drakec9680921999-12-13 16:37:25 +000010093#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
Fred Draked86ed291999-12-15 15:34:33 +000010120#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010122#endif
10123#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010125#endif
Fred Drakec9680921999-12-13 16:37:25 +000010126#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
Fred Draked86ed291999-12-15 15:34:33 +000010231#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010233#endif
Fred Drakec9680921999-12-13 16:37:25 +000010234#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369};
10370
10371static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010372conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010373{
10374 return conv_confname(arg, valuep, posix_constants_sysconf,
10375 sizeof(posix_constants_sysconf)
10376 / sizeof(struct constdef));
10377}
10378
Larry Hastings2f936352014-08-05 14:04:04 +100010379
10380/*[clinic input]
10381os.sysconf -> long
10382 name: sysconf_confname
10383 /
10384
10385Return an integer-valued system configuration variable.
10386[clinic start generated code]*/
10387
Larry Hastings2f936352014-08-05 14:04:04 +100010388static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010389os_sysconf_impl(PyObject *module, int name)
10390/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010391{
10392 long value;
10393
10394 errno = 0;
10395 value = sysconf(name);
10396 if (value == -1 && errno != 0)
10397 posix_error();
10398 return value;
10399}
10400#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010401
10402
Fred Drakebec628d1999-12-15 18:31:10 +000010403/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010404 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010405 * the exported dictionaries that are used to publish information about the
10406 * names available on the host platform.
10407 *
10408 * Sorting the table at runtime ensures that the table is properly ordered
10409 * when used, even for platforms we're not able to test on. It also makes
10410 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010411 */
Fred Drakebec628d1999-12-15 18:31:10 +000010412
10413static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010414cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010415{
10416 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010418 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010420
10421 return strcmp(c1->name, c2->name);
10422}
10423
10424static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010425setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010426 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010427{
Fred Drakebec628d1999-12-15 18:31:10 +000010428 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010429 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010430
10431 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10432 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010433 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010435
Barry Warsaw3155db32000-04-13 15:20:40 +000010436 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 PyObject *o = PyLong_FromLong(table[i].value);
10438 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10439 Py_XDECREF(o);
10440 Py_DECREF(d);
10441 return -1;
10442 }
10443 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010444 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010445 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010446}
10447
Fred Drakebec628d1999-12-15 18:31:10 +000010448/* Return -1 on failure, 0 on success. */
10449static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010450setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010451{
10452#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010453 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010454 sizeof(posix_constants_pathconf)
10455 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010456 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010457 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010458#endif
10459#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010460 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010461 sizeof(posix_constants_confstr)
10462 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010463 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010464 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010465#endif
10466#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010467 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010468 sizeof(posix_constants_sysconf)
10469 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010470 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010471 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010472#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010473 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010474}
Fred Draked86ed291999-12-15 15:34:33 +000010475
10476
Larry Hastings2f936352014-08-05 14:04:04 +100010477/*[clinic input]
10478os.abort
10479
10480Abort the interpreter immediately.
10481
10482This function 'dumps core' or otherwise fails in the hardest way possible
10483on the hosting operating system. This function never returns.
10484[clinic start generated code]*/
10485
Larry Hastings2f936352014-08-05 14:04:04 +100010486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010487os_abort_impl(PyObject *module)
10488/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010489{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010490 abort();
10491 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010492#ifndef __clang__
10493 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10494 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10495 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010496 Py_FatalError("abort() called from Python code didn't abort!");
10497 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010498#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010499}
Fred Drakebec628d1999-12-15 18:31:10 +000010500
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010501#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010502/* Grab ShellExecute dynamically from shell32 */
10503static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010504static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10505 LPCWSTR, INT);
10506static int
10507check_ShellExecute()
10508{
10509 HINSTANCE hShell32;
10510
10511 /* only recheck */
10512 if (-1 == has_ShellExecute) {
10513 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010514 /* Security note: this call is not vulnerable to "DLL hijacking".
10515 SHELL32 is part of "KnownDLLs" and so Windows always load
10516 the system SHELL32.DLL, even if there is another SHELL32.DLL
10517 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010518 hShell32 = LoadLibraryW(L"SHELL32");
10519 Py_END_ALLOW_THREADS
10520 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010521 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10522 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010523 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010524 } else {
10525 has_ShellExecute = 0;
10526 }
10527 }
10528 return has_ShellExecute;
10529}
10530
10531
Steve Dowercc16be82016-09-08 10:35:16 -070010532/*[clinic input]
10533os.startfile
10534 filepath: path_t
10535 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010536
Steve Dowercc16be82016-09-08 10:35:16 -070010537startfile(filepath [, operation])
10538
10539Start a file with its associated application.
10540
10541When "operation" is not specified or "open", this acts like
10542double-clicking the file in Explorer, or giving the file name as an
10543argument to the DOS "start" command: the file is opened with whatever
10544application (if any) its extension is associated.
10545When another "operation" is given, it specifies what should be done with
10546the file. A typical operation is "print".
10547
10548startfile returns as soon as the associated application is launched.
10549There is no option to wait for the application to close, and no way
10550to retrieve the application's exit status.
10551
10552The filepath is relative to the current directory. If you want to use
10553an absolute path, make sure the first character is not a slash ("/");
10554the underlying Win32 ShellExecute function doesn't work if it is.
10555[clinic start generated code]*/
10556
10557static PyObject *
10558os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10559/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10560{
10561 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010562
10563 if(!check_ShellExecute()) {
10564 /* If the OS doesn't have ShellExecute, return a
10565 NotImplementedError. */
10566 return PyErr_Format(PyExc_NotImplementedError,
10567 "startfile not available on this platform");
10568 }
10569
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010571 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010572 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 Py_END_ALLOW_THREADS
10574
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010576 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010577 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 }
Steve Dowercc16be82016-09-08 10:35:16 -070010579 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010580}
Larry Hastings2f936352014-08-05 14:04:04 +100010581#endif /* MS_WINDOWS */
10582
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010583
Martin v. Löwis438b5342002-12-27 10:16:42 +000010584#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010585/*[clinic input]
10586os.getloadavg
10587
10588Return average recent system load information.
10589
10590Return the number of processes in the system run queue averaged over
10591the last 1, 5, and 15 minutes as a tuple of three floats.
10592Raises OSError if the load average was unobtainable.
10593[clinic start generated code]*/
10594
Larry Hastings2f936352014-08-05 14:04:04 +100010595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010596os_getloadavg_impl(PyObject *module)
10597/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010598{
10599 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010600 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010601 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10602 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010603 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010604 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010605}
Larry Hastings2f936352014-08-05 14:04:04 +100010606#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010607
Larry Hastings2f936352014-08-05 14:04:04 +100010608
10609/*[clinic input]
10610os.device_encoding
10611 fd: int
10612
10613Return a string describing the encoding of a terminal's file descriptor.
10614
10615The file descriptor must be attached to a terminal.
10616If the device is not a terminal, return None.
10617[clinic start generated code]*/
10618
Larry Hastings2f936352014-08-05 14:04:04 +100010619static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010620os_device_encoding_impl(PyObject *module, int fd)
10621/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010622{
Brett Cannonefb00c02012-02-29 18:31:31 -050010623 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010624}
10625
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010626
Larry Hastings2f936352014-08-05 14:04:04 +100010627#ifdef HAVE_SETRESUID
10628/*[clinic input]
10629os.setresuid
10630
10631 ruid: uid_t
10632 euid: uid_t
10633 suid: uid_t
10634 /
10635
10636Set the current process's real, effective, and saved user ids.
10637[clinic start generated code]*/
10638
Larry Hastings2f936352014-08-05 14:04:04 +100010639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010640os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10641/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010642{
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 if (setresuid(ruid, euid, suid) < 0)
10644 return posix_error();
10645 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010646}
Larry Hastings2f936352014-08-05 14:04:04 +100010647#endif /* HAVE_SETRESUID */
10648
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010649
10650#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010651/*[clinic input]
10652os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010653
Larry Hastings2f936352014-08-05 14:04:04 +100010654 rgid: gid_t
10655 egid: gid_t
10656 sgid: gid_t
10657 /
10658
10659Set the current process's real, effective, and saved group ids.
10660[clinic start generated code]*/
10661
Larry Hastings2f936352014-08-05 14:04:04 +100010662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010663os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10664/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010665{
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 if (setresgid(rgid, egid, sgid) < 0)
10667 return posix_error();
10668 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010669}
Larry Hastings2f936352014-08-05 14:04:04 +100010670#endif /* HAVE_SETRESGID */
10671
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010672
10673#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010674/*[clinic input]
10675os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010676
Larry Hastings2f936352014-08-05 14:04:04 +100010677Return a tuple of the current process's real, effective, and saved user ids.
10678[clinic start generated code]*/
10679
Larry Hastings2f936352014-08-05 14:04:04 +100010680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010681os_getresuid_impl(PyObject *module)
10682/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010683{
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 if (getresuid(&ruid, &euid, &suid) < 0)
10686 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010687 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10688 _PyLong_FromUid(euid),
10689 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010690}
Larry Hastings2f936352014-08-05 14:04:04 +100010691#endif /* HAVE_GETRESUID */
10692
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010693
10694#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010695/*[clinic input]
10696os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010697
Larry Hastings2f936352014-08-05 14:04:04 +100010698Return a tuple of the current process's real, effective, and saved group ids.
10699[clinic start generated code]*/
10700
Larry Hastings2f936352014-08-05 14:04:04 +100010701static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010702os_getresgid_impl(PyObject *module)
10703/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010704{
10705 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 if (getresgid(&rgid, &egid, &sgid) < 0)
10707 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010708 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10709 _PyLong_FromGid(egid),
10710 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010711}
Larry Hastings2f936352014-08-05 14:04:04 +100010712#endif /* HAVE_GETRESGID */
10713
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010714
Benjamin Peterson9428d532011-09-14 11:45:52 -040010715#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010716/*[clinic input]
10717os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010718
Larry Hastings2f936352014-08-05 14:04:04 +100010719 path: path_t(allow_fd=True)
10720 attribute: path_t
10721 *
10722 follow_symlinks: bool = True
10723
10724Return the value of extended attribute attribute on path.
10725
10726path may be either a string or an open file descriptor.
10727If follow_symlinks is False, and the last element of the path is a symbolic
10728 link, getxattr will examine the symbolic link itself instead of the file
10729 the link points to.
10730
10731[clinic start generated code]*/
10732
Larry Hastings2f936352014-08-05 14:04:04 +100010733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010734os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010735 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010736/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010737{
10738 Py_ssize_t i;
10739 PyObject *buffer = NULL;
10740
10741 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10742 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743
Larry Hastings9cf065c2012-06-22 16:30:09 -070010744 for (i = 0; ; i++) {
10745 void *ptr;
10746 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010747 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010748 Py_ssize_t buffer_size = buffer_sizes[i];
10749 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010750 path_error(path);
10751 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010752 }
10753 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10754 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010755 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010756 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010757
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010759 if (path->fd >= 0)
10760 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010762 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763 else
Larry Hastings2f936352014-08-05 14:04:04 +100010764 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010766
Larry Hastings9cf065c2012-06-22 16:30:09 -070010767 if (result < 0) {
10768 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010769 if (errno == ERANGE)
10770 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010771 path_error(path);
10772 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010774
Larry Hastings9cf065c2012-06-22 16:30:09 -070010775 if (result != buffer_size) {
10776 /* Can only shrink. */
10777 _PyBytes_Resize(&buffer, result);
10778 }
10779 break;
10780 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010781
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783}
10784
Larry Hastings2f936352014-08-05 14:04:04 +100010785
10786/*[clinic input]
10787os.setxattr
10788
10789 path: path_t(allow_fd=True)
10790 attribute: path_t
10791 value: Py_buffer
10792 flags: int = 0
10793 *
10794 follow_symlinks: bool = True
10795
10796Set extended attribute attribute on path to value.
10797
10798path may be either a string or an open file descriptor.
10799If follow_symlinks is False, and the last element of the path is a symbolic
10800 link, setxattr will modify the symbolic link itself instead of the file
10801 the link points to.
10802
10803[clinic start generated code]*/
10804
Benjamin Peterson799bd802011-08-31 22:15:17 -040010805static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010806os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010807 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010808/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010809{
Larry Hastings2f936352014-08-05 14:04:04 +100010810 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010811
Larry Hastings2f936352014-08-05 14:04:04 +100010812 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010813 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814
Benjamin Peterson799bd802011-08-31 22:15:17 -040010815 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010816 if (path->fd > -1)
10817 result = fsetxattr(path->fd, attribute->narrow,
10818 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010819 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010820 result = setxattr(path->narrow, attribute->narrow,
10821 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010822 else
Larry Hastings2f936352014-08-05 14:04:04 +100010823 result = lsetxattr(path->narrow, attribute->narrow,
10824 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010825 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010826
Larry Hastings9cf065c2012-06-22 16:30:09 -070010827 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010828 path_error(path);
10829 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010830 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010831
Larry Hastings2f936352014-08-05 14:04:04 +100010832 Py_RETURN_NONE;
10833}
10834
10835
10836/*[clinic input]
10837os.removexattr
10838
10839 path: path_t(allow_fd=True)
10840 attribute: path_t
10841 *
10842 follow_symlinks: bool = True
10843
10844Remove extended attribute attribute on path.
10845
10846path may be either a string or an open file descriptor.
10847If follow_symlinks is False, and the last element of the path is a symbolic
10848 link, removexattr will modify the symbolic link itself instead of the file
10849 the link points to.
10850
10851[clinic start generated code]*/
10852
Larry Hastings2f936352014-08-05 14:04:04 +100010853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010854os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010855 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010856/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010857{
10858 ssize_t result;
10859
10860 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10861 return NULL;
10862
10863 Py_BEGIN_ALLOW_THREADS;
10864 if (path->fd > -1)
10865 result = fremovexattr(path->fd, attribute->narrow);
10866 else if (follow_symlinks)
10867 result = removexattr(path->narrow, attribute->narrow);
10868 else
10869 result = lremovexattr(path->narrow, attribute->narrow);
10870 Py_END_ALLOW_THREADS;
10871
10872 if (result) {
10873 return path_error(path);
10874 }
10875
10876 Py_RETURN_NONE;
10877}
10878
10879
10880/*[clinic input]
10881os.listxattr
10882
10883 path: path_t(allow_fd=True, nullable=True) = None
10884 *
10885 follow_symlinks: bool = True
10886
10887Return a list of extended attributes on path.
10888
10889path may be either None, a string, or an open file descriptor.
10890if path is None, listxattr will examine the current directory.
10891If follow_symlinks is False, and the last element of the path is a symbolic
10892 link, listxattr will examine the symbolic link itself instead of the file
10893 the link points to.
10894[clinic start generated code]*/
10895
Larry Hastings2f936352014-08-05 14:04:04 +100010896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010897os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10898/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010899{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010900 Py_ssize_t i;
10901 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010902 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010903 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904
Larry Hastings2f936352014-08-05 14:04:04 +100010905 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010906 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010907
Larry Hastings2f936352014-08-05 14:04:04 +100010908 name = path->narrow ? path->narrow : ".";
10909
Larry Hastings9cf065c2012-06-22 16:30:09 -070010910 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010911 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010912 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010913 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010914 Py_ssize_t buffer_size = buffer_sizes[i];
10915 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010916 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010917 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010918 break;
10919 }
10920 buffer = PyMem_MALLOC(buffer_size);
10921 if (!buffer) {
10922 PyErr_NoMemory();
10923 break;
10924 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010925
Larry Hastings9cf065c2012-06-22 16:30:09 -070010926 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010927 if (path->fd > -1)
10928 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010929 else if (follow_symlinks)
10930 length = listxattr(name, buffer, buffer_size);
10931 else
10932 length = llistxattr(name, buffer, buffer_size);
10933 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010934
Larry Hastings9cf065c2012-06-22 16:30:09 -070010935 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010936 if (errno == ERANGE) {
10937 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010938 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010939 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010940 }
Larry Hastings2f936352014-08-05 14:04:04 +100010941 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010942 break;
10943 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010944
Larry Hastings9cf065c2012-06-22 16:30:09 -070010945 result = PyList_New(0);
10946 if (!result) {
10947 goto exit;
10948 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010949
Larry Hastings9cf065c2012-06-22 16:30:09 -070010950 end = buffer + length;
10951 for (trace = start = buffer; trace != end; trace++) {
10952 if (!*trace) {
10953 int error;
10954 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10955 trace - start);
10956 if (!attribute) {
10957 Py_DECREF(result);
10958 result = NULL;
10959 goto exit;
10960 }
10961 error = PyList_Append(result, attribute);
10962 Py_DECREF(attribute);
10963 if (error) {
10964 Py_DECREF(result);
10965 result = NULL;
10966 goto exit;
10967 }
10968 start = trace + 1;
10969 }
10970 }
10971 break;
10972 }
10973exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010974 if (buffer)
10975 PyMem_FREE(buffer);
10976 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010977}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010978#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010979
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010980
Larry Hastings2f936352014-08-05 14:04:04 +100010981/*[clinic input]
10982os.urandom
10983
10984 size: Py_ssize_t
10985 /
10986
10987Return a bytes object containing random bytes suitable for cryptographic use.
10988[clinic start generated code]*/
10989
Larry Hastings2f936352014-08-05 14:04:04 +100010990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010991os_urandom_impl(PyObject *module, Py_ssize_t size)
10992/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010993{
10994 PyObject *bytes;
10995 int result;
10996
Georg Brandl2fb477c2012-02-21 00:33:36 +010010997 if (size < 0)
10998 return PyErr_Format(PyExc_ValueError,
10999 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011000 bytes = PyBytes_FromStringAndSize(NULL, size);
11001 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011002 return NULL;
11003
Victor Stinnere66987e2016-09-06 16:33:52 -070011004 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011005 if (result == -1) {
11006 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011007 return NULL;
11008 }
Larry Hastings2f936352014-08-05 14:04:04 +100011009 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011010}
11011
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011012/* Terminal size querying */
11013
11014static PyTypeObject TerminalSizeType;
11015
11016PyDoc_STRVAR(TerminalSize_docstring,
11017 "A tuple of (columns, lines) for holding terminal window size");
11018
11019static PyStructSequence_Field TerminalSize_fields[] = {
11020 {"columns", "width of the terminal window in characters"},
11021 {"lines", "height of the terminal window in characters"},
11022 {NULL, NULL}
11023};
11024
11025static PyStructSequence_Desc TerminalSize_desc = {
11026 "os.terminal_size",
11027 TerminalSize_docstring,
11028 TerminalSize_fields,
11029 2,
11030};
11031
11032#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011033/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011034PyDoc_STRVAR(termsize__doc__,
11035 "Return the size of the terminal window as (columns, lines).\n" \
11036 "\n" \
11037 "The optional argument fd (default standard output) specifies\n" \
11038 "which file descriptor should be queried.\n" \
11039 "\n" \
11040 "If the file descriptor is not connected to a terminal, an OSError\n" \
11041 "is thrown.\n" \
11042 "\n" \
11043 "This function will only be defined if an implementation is\n" \
11044 "available for this system.\n" \
11045 "\n" \
11046 "shutil.get_terminal_size is the high-level function which should \n" \
11047 "normally be used, os.get_terminal_size is the low-level implementation.");
11048
11049static PyObject*
11050get_terminal_size(PyObject *self, PyObject *args)
11051{
11052 int columns, lines;
11053 PyObject *termsize;
11054
11055 int fd = fileno(stdout);
11056 /* Under some conditions stdout may not be connected and
11057 * fileno(stdout) may point to an invalid file descriptor. For example
11058 * GUI apps don't have valid standard streams by default.
11059 *
11060 * If this happens, and the optional fd argument is not present,
11061 * the ioctl below will fail returning EBADF. This is what we want.
11062 */
11063
11064 if (!PyArg_ParseTuple(args, "|i", &fd))
11065 return NULL;
11066
11067#ifdef TERMSIZE_USE_IOCTL
11068 {
11069 struct winsize w;
11070 if (ioctl(fd, TIOCGWINSZ, &w))
11071 return PyErr_SetFromErrno(PyExc_OSError);
11072 columns = w.ws_col;
11073 lines = w.ws_row;
11074 }
11075#endif /* TERMSIZE_USE_IOCTL */
11076
11077#ifdef TERMSIZE_USE_CONIO
11078 {
11079 DWORD nhandle;
11080 HANDLE handle;
11081 CONSOLE_SCREEN_BUFFER_INFO csbi;
11082 switch (fd) {
11083 case 0: nhandle = STD_INPUT_HANDLE;
11084 break;
11085 case 1: nhandle = STD_OUTPUT_HANDLE;
11086 break;
11087 case 2: nhandle = STD_ERROR_HANDLE;
11088 break;
11089 default:
11090 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11091 }
11092 handle = GetStdHandle(nhandle);
11093 if (handle == NULL)
11094 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11095 if (handle == INVALID_HANDLE_VALUE)
11096 return PyErr_SetFromWindowsErr(0);
11097
11098 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11099 return PyErr_SetFromWindowsErr(0);
11100
11101 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11102 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11103 }
11104#endif /* TERMSIZE_USE_CONIO */
11105
11106 termsize = PyStructSequence_New(&TerminalSizeType);
11107 if (termsize == NULL)
11108 return NULL;
11109 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11110 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11111 if (PyErr_Occurred()) {
11112 Py_DECREF(termsize);
11113 return NULL;
11114 }
11115 return termsize;
11116}
11117#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11118
Larry Hastings2f936352014-08-05 14:04:04 +100011119
11120/*[clinic input]
11121os.cpu_count
11122
Charles-François Natali80d62e62015-08-13 20:37:08 +010011123Return the number of CPUs in the system; return None if indeterminable.
11124
11125This number is not equivalent to the number of CPUs the current process can
11126use. The number of usable CPUs can be obtained with
11127``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011128[clinic start generated code]*/
11129
Larry Hastings2f936352014-08-05 14:04:04 +100011130static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011131os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011132/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011133{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011134 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011135#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011136 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11137 Need to fallback to Vista behavior if this call isn't present */
11138 HINSTANCE hKernel32;
11139 hKernel32 = GetModuleHandleW(L"KERNEL32");
11140
11141 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11142 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11143 "GetMaximumProcessorCount");
11144 if (_GetMaximumProcessorCount != NULL) {
11145 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11146 }
11147 else {
11148 SYSTEM_INFO sysinfo;
11149 GetSystemInfo(&sysinfo);
11150 ncpu = sysinfo.dwNumberOfProcessors;
11151 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011152#elif defined(__hpux)
11153 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11154#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11155 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011156#elif defined(__DragonFly__) || \
11157 defined(__OpenBSD__) || \
11158 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011159 defined(__NetBSD__) || \
11160 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011161 int mib[2];
11162 size_t len = sizeof(ncpu);
11163 mib[0] = CTL_HW;
11164 mib[1] = HW_NCPU;
11165 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11166 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011167#endif
11168 if (ncpu >= 1)
11169 return PyLong_FromLong(ncpu);
11170 else
11171 Py_RETURN_NONE;
11172}
11173
Victor Stinnerdaf45552013-08-28 00:53:59 +020011174
Larry Hastings2f936352014-08-05 14:04:04 +100011175/*[clinic input]
11176os.get_inheritable -> bool
11177
11178 fd: int
11179 /
11180
11181Get the close-on-exe flag of the specified file descriptor.
11182[clinic start generated code]*/
11183
Larry Hastings2f936352014-08-05 14:04:04 +100011184static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011185os_get_inheritable_impl(PyObject *module, int fd)
11186/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011187{
Steve Dower8fc89802015-04-12 00:26:27 -040011188 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011189 _Py_BEGIN_SUPPRESS_IPH
11190 return_value = _Py_get_inheritable(fd);
11191 _Py_END_SUPPRESS_IPH
11192 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011193}
11194
11195
11196/*[clinic input]
11197os.set_inheritable
11198 fd: int
11199 inheritable: int
11200 /
11201
11202Set the inheritable flag of the specified file descriptor.
11203[clinic start generated code]*/
11204
Larry Hastings2f936352014-08-05 14:04:04 +100011205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011206os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11207/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011208{
Steve Dower8fc89802015-04-12 00:26:27 -040011209 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011210
Steve Dower8fc89802015-04-12 00:26:27 -040011211 _Py_BEGIN_SUPPRESS_IPH
11212 result = _Py_set_inheritable(fd, inheritable, NULL);
11213 _Py_END_SUPPRESS_IPH
11214 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011215 return NULL;
11216 Py_RETURN_NONE;
11217}
11218
11219
11220#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011221/*[clinic input]
11222os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011223 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011224 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011225
Larry Hastings2f936352014-08-05 14:04:04 +100011226Get the close-on-exe flag of the specified file descriptor.
11227[clinic start generated code]*/
11228
Larry Hastings2f936352014-08-05 14:04:04 +100011229static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011230os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011231/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011232{
11233 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011234
11235 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11236 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011237 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011238 }
11239
Larry Hastings2f936352014-08-05 14:04:04 +100011240 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011241}
11242
Victor Stinnerdaf45552013-08-28 00:53:59 +020011243
Larry Hastings2f936352014-08-05 14:04:04 +100011244/*[clinic input]
11245os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011246 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011247 inheritable: bool
11248 /
11249
11250Set the inheritable flag of the specified handle.
11251[clinic start generated code]*/
11252
Larry Hastings2f936352014-08-05 14:04:04 +100011253static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011254os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011255 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011256/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011257{
11258 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011259 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11260 PyErr_SetFromWindowsErr(0);
11261 return NULL;
11262 }
11263 Py_RETURN_NONE;
11264}
Larry Hastings2f936352014-08-05 14:04:04 +100011265#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011266
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011267#ifndef MS_WINDOWS
11268PyDoc_STRVAR(get_blocking__doc__,
11269 "get_blocking(fd) -> bool\n" \
11270 "\n" \
11271 "Get the blocking mode of the file descriptor:\n" \
11272 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11273
11274static PyObject*
11275posix_get_blocking(PyObject *self, PyObject *args)
11276{
11277 int fd;
11278 int blocking;
11279
11280 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11281 return NULL;
11282
Steve Dower8fc89802015-04-12 00:26:27 -040011283 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011284 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011285 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011286 if (blocking < 0)
11287 return NULL;
11288 return PyBool_FromLong(blocking);
11289}
11290
11291PyDoc_STRVAR(set_blocking__doc__,
11292 "set_blocking(fd, blocking)\n" \
11293 "\n" \
11294 "Set the blocking mode of the specified file descriptor.\n" \
11295 "Set the O_NONBLOCK flag if blocking is False,\n" \
11296 "clear the O_NONBLOCK flag otherwise.");
11297
11298static PyObject*
11299posix_set_blocking(PyObject *self, PyObject *args)
11300{
Steve Dower8fc89802015-04-12 00:26:27 -040011301 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011302
11303 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11304 return NULL;
11305
Steve Dower8fc89802015-04-12 00:26:27 -040011306 _Py_BEGIN_SUPPRESS_IPH
11307 result = _Py_set_blocking(fd, blocking);
11308 _Py_END_SUPPRESS_IPH
11309 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011310 return NULL;
11311 Py_RETURN_NONE;
11312}
11313#endif /* !MS_WINDOWS */
11314
11315
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011316/*[clinic input]
11317class os.DirEntry "DirEntry *" "&DirEntryType"
11318[clinic start generated code]*/
11319/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011320
11321typedef struct {
11322 PyObject_HEAD
11323 PyObject *name;
11324 PyObject *path;
11325 PyObject *stat;
11326 PyObject *lstat;
11327#ifdef MS_WINDOWS
11328 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011329 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011330 int got_file_index;
11331#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011332#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011333 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011334#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011335 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011336 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011337#endif
11338} DirEntry;
11339
11340static void
11341DirEntry_dealloc(DirEntry *entry)
11342{
11343 Py_XDECREF(entry->name);
11344 Py_XDECREF(entry->path);
11345 Py_XDECREF(entry->stat);
11346 Py_XDECREF(entry->lstat);
11347 Py_TYPE(entry)->tp_free((PyObject *)entry);
11348}
11349
11350/* Forward reference */
11351static int
11352DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11353
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011354/*[clinic input]
11355os.DirEntry.is_symlink -> bool
11356
11357Return True if the entry is a symbolic link; cached per entry.
11358[clinic start generated code]*/
11359
Victor Stinner6036e442015-03-08 01:58:04 +010011360static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011361os_DirEntry_is_symlink_impl(DirEntry *self)
11362/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011363{
11364#ifdef MS_WINDOWS
11365 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011366#elif defined(HAVE_DIRENT_D_TYPE)
11367 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011368 if (self->d_type != DT_UNKNOWN)
11369 return self->d_type == DT_LNK;
11370 else
11371 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011372#else
11373 /* POSIX without d_type */
11374 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011375#endif
11376}
11377
11378static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011379DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11380{
11381 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011382 STRUCT_STAT st;
11383 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011384
11385#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011386 if (!PyUnicode_FSDecoder(self->path, &ub))
11387 return NULL;
11388 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011389#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011390 if (!PyUnicode_FSConverter(self->path, &ub))
11391 return NULL;
11392 const char *path = PyBytes_AS_STRING(ub);
11393 if (self->dir_fd != DEFAULT_DIR_FD) {
11394#ifdef HAVE_FSTATAT
11395 result = fstatat(self->dir_fd, path, &st,
11396 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11397#else
11398 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11399 return NULL;
11400#endif /* HAVE_FSTATAT */
11401 }
11402 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011403#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011404 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011405 if (follow_symlinks)
11406 result = STAT(path, &st);
11407 else
11408 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011409 }
11410 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011411
11412 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011413 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011414
11415 return _pystat_fromstructstat(&st);
11416}
11417
11418static PyObject *
11419DirEntry_get_lstat(DirEntry *self)
11420{
11421 if (!self->lstat) {
11422#ifdef MS_WINDOWS
11423 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11424#else /* POSIX */
11425 self->lstat = DirEntry_fetch_stat(self, 0);
11426#endif
11427 }
11428 Py_XINCREF(self->lstat);
11429 return self->lstat;
11430}
11431
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011432/*[clinic input]
11433os.DirEntry.stat
11434 *
11435 follow_symlinks: bool = True
11436
11437Return stat_result object for the entry; cached per entry.
11438[clinic start generated code]*/
11439
Victor Stinner6036e442015-03-08 01:58:04 +010011440static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011441os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11442/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011443{
11444 if (!follow_symlinks)
11445 return DirEntry_get_lstat(self);
11446
11447 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011448 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011449 if (result == -1)
11450 return NULL;
11451 else if (result)
11452 self->stat = DirEntry_fetch_stat(self, 1);
11453 else
11454 self->stat = DirEntry_get_lstat(self);
11455 }
11456
11457 Py_XINCREF(self->stat);
11458 return self->stat;
11459}
11460
Victor Stinner6036e442015-03-08 01:58:04 +010011461/* Set exception and return -1 on error, 0 for False, 1 for True */
11462static int
11463DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11464{
11465 PyObject *stat = NULL;
11466 PyObject *st_mode = NULL;
11467 long mode;
11468 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011469#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011470 int is_symlink;
11471 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011472#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011473#ifdef MS_WINDOWS
11474 unsigned long dir_bits;
11475#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011476 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011477
11478#ifdef MS_WINDOWS
11479 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11480 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011481#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011482 is_symlink = self->d_type == DT_LNK;
11483 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11484#endif
11485
Victor Stinner35a97c02015-03-08 02:59:09 +010011486#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011487 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011488#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011489 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011490 if (!stat) {
11491 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11492 /* If file doesn't exist (anymore), then return False
11493 (i.e., say it's not a file/directory) */
11494 PyErr_Clear();
11495 return 0;
11496 }
11497 goto error;
11498 }
11499 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11500 if (!st_mode)
11501 goto error;
11502
11503 mode = PyLong_AsLong(st_mode);
11504 if (mode == -1 && PyErr_Occurred())
11505 goto error;
11506 Py_CLEAR(st_mode);
11507 Py_CLEAR(stat);
11508 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011509#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011510 }
11511 else if (is_symlink) {
11512 assert(mode_bits != S_IFLNK);
11513 result = 0;
11514 }
11515 else {
11516 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11517#ifdef MS_WINDOWS
11518 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11519 if (mode_bits == S_IFDIR)
11520 result = dir_bits != 0;
11521 else
11522 result = dir_bits == 0;
11523#else /* POSIX */
11524 if (mode_bits == S_IFDIR)
11525 result = self->d_type == DT_DIR;
11526 else
11527 result = self->d_type == DT_REG;
11528#endif
11529 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011530#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011531
11532 return result;
11533
11534error:
11535 Py_XDECREF(st_mode);
11536 Py_XDECREF(stat);
11537 return -1;
11538}
11539
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011540/*[clinic input]
11541os.DirEntry.is_dir -> bool
11542 *
11543 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011544
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011545Return True if the entry is a directory; cached per entry.
11546[clinic start generated code]*/
11547
11548static int
11549os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11550/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11551{
11552 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011553}
11554
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011555/*[clinic input]
11556os.DirEntry.is_file -> bool
11557 *
11558 follow_symlinks: bool = True
11559
11560Return True if the entry is a file; cached per entry.
11561[clinic start generated code]*/
11562
11563static int
11564os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11565/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011566{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011567 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011568}
11569
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011570/*[clinic input]
11571os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011572
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011573Return inode of the entry; cached per entry.
11574[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011575
11576static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011577os_DirEntry_inode_impl(DirEntry *self)
11578/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011579{
11580#ifdef MS_WINDOWS
11581 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011582 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011583 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011584 STRUCT_STAT stat;
11585 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011586
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011587 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011588 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011589 path = PyUnicode_AsUnicode(unicode);
11590 result = LSTAT(path, &stat);
11591 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011592
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011593 if (result != 0)
11594 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011595
11596 self->win32_file_index = stat.st_ino;
11597 self->got_file_index = 1;
11598 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011599 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11600 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011601#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011602 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11603 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011604#endif
11605}
11606
11607static PyObject *
11608DirEntry_repr(DirEntry *self)
11609{
11610 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11611}
11612
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011613/*[clinic input]
11614os.DirEntry.__fspath__
11615
11616Returns the path for the entry.
11617[clinic start generated code]*/
11618
Brett Cannon96881cd2016-06-10 14:37:21 -070011619static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011620os_DirEntry___fspath___impl(DirEntry *self)
11621/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011622{
11623 Py_INCREF(self->path);
11624 return self->path;
11625}
11626
Victor Stinner6036e442015-03-08 01:58:04 +010011627static PyMemberDef DirEntry_members[] = {
11628 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11629 "the entry's base filename, relative to scandir() \"path\" argument"},
11630 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11631 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11632 {NULL}
11633};
11634
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011635#include "clinic/posixmodule.c.h"
11636
Victor Stinner6036e442015-03-08 01:58:04 +010011637static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011638 OS_DIRENTRY_IS_DIR_METHODDEF
11639 OS_DIRENTRY_IS_FILE_METHODDEF
11640 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11641 OS_DIRENTRY_STAT_METHODDEF
11642 OS_DIRENTRY_INODE_METHODDEF
11643 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011644 {NULL}
11645};
11646
Benjamin Peterson5646de42015-04-12 17:56:34 -040011647static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011648 PyVarObject_HEAD_INIT(NULL, 0)
11649 MODNAME ".DirEntry", /* tp_name */
11650 sizeof(DirEntry), /* tp_basicsize */
11651 0, /* tp_itemsize */
11652 /* methods */
11653 (destructor)DirEntry_dealloc, /* tp_dealloc */
11654 0, /* tp_print */
11655 0, /* tp_getattr */
11656 0, /* tp_setattr */
11657 0, /* tp_compare */
11658 (reprfunc)DirEntry_repr, /* tp_repr */
11659 0, /* tp_as_number */
11660 0, /* tp_as_sequence */
11661 0, /* tp_as_mapping */
11662 0, /* tp_hash */
11663 0, /* tp_call */
11664 0, /* tp_str */
11665 0, /* tp_getattro */
11666 0, /* tp_setattro */
11667 0, /* tp_as_buffer */
11668 Py_TPFLAGS_DEFAULT, /* tp_flags */
11669 0, /* tp_doc */
11670 0, /* tp_traverse */
11671 0, /* tp_clear */
11672 0, /* tp_richcompare */
11673 0, /* tp_weaklistoffset */
11674 0, /* tp_iter */
11675 0, /* tp_iternext */
11676 DirEntry_methods, /* tp_methods */
11677 DirEntry_members, /* tp_members */
11678};
11679
11680#ifdef MS_WINDOWS
11681
11682static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011683join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011684{
11685 Py_ssize_t path_len;
11686 Py_ssize_t size;
11687 wchar_t *result;
11688 wchar_t ch;
11689
11690 if (!path_wide) { /* Default arg: "." */
11691 path_wide = L".";
11692 path_len = 1;
11693 }
11694 else {
11695 path_len = wcslen(path_wide);
11696 }
11697
11698 /* The +1's are for the path separator and the NUL */
11699 size = path_len + 1 + wcslen(filename) + 1;
11700 result = PyMem_New(wchar_t, size);
11701 if (!result) {
11702 PyErr_NoMemory();
11703 return NULL;
11704 }
11705 wcscpy(result, path_wide);
11706 if (path_len > 0) {
11707 ch = result[path_len - 1];
11708 if (ch != SEP && ch != ALTSEP && ch != L':')
11709 result[path_len++] = SEP;
11710 wcscpy(result + path_len, filename);
11711 }
11712 return result;
11713}
11714
11715static PyObject *
11716DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11717{
11718 DirEntry *entry;
11719 BY_HANDLE_FILE_INFORMATION file_info;
11720 ULONG reparse_tag;
11721 wchar_t *joined_path;
11722
11723 entry = PyObject_New(DirEntry, &DirEntryType);
11724 if (!entry)
11725 return NULL;
11726 entry->name = NULL;
11727 entry->path = NULL;
11728 entry->stat = NULL;
11729 entry->lstat = NULL;
11730 entry->got_file_index = 0;
11731
11732 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11733 if (!entry->name)
11734 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011735 if (path->narrow) {
11736 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11737 if (!entry->name)
11738 goto error;
11739 }
Victor Stinner6036e442015-03-08 01:58:04 +010011740
11741 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11742 if (!joined_path)
11743 goto error;
11744
11745 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11746 PyMem_Free(joined_path);
11747 if (!entry->path)
11748 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011749 if (path->narrow) {
11750 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11751 if (!entry->path)
11752 goto error;
11753 }
Victor Stinner6036e442015-03-08 01:58:04 +010011754
Steve Dowercc16be82016-09-08 10:35:16 -070011755 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011756 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11757
11758 return (PyObject *)entry;
11759
11760error:
11761 Py_DECREF(entry);
11762 return NULL;
11763}
11764
11765#else /* POSIX */
11766
11767static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011768join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011769{
11770 Py_ssize_t path_len;
11771 Py_ssize_t size;
11772 char *result;
11773
11774 if (!path_narrow) { /* Default arg: "." */
11775 path_narrow = ".";
11776 path_len = 1;
11777 }
11778 else {
11779 path_len = strlen(path_narrow);
11780 }
11781
11782 if (filename_len == -1)
11783 filename_len = strlen(filename);
11784
11785 /* The +1's are for the path separator and the NUL */
11786 size = path_len + 1 + filename_len + 1;
11787 result = PyMem_New(char, size);
11788 if (!result) {
11789 PyErr_NoMemory();
11790 return NULL;
11791 }
11792 strcpy(result, path_narrow);
11793 if (path_len > 0 && result[path_len - 1] != '/')
11794 result[path_len++] = '/';
11795 strcpy(result + path_len, filename);
11796 return result;
11797}
11798
11799static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011800DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011801 ino_t d_ino
11802#ifdef HAVE_DIRENT_D_TYPE
11803 , unsigned char d_type
11804#endif
11805 )
Victor Stinner6036e442015-03-08 01:58:04 +010011806{
11807 DirEntry *entry;
11808 char *joined_path;
11809
11810 entry = PyObject_New(DirEntry, &DirEntryType);
11811 if (!entry)
11812 return NULL;
11813 entry->name = NULL;
11814 entry->path = NULL;
11815 entry->stat = NULL;
11816 entry->lstat = NULL;
11817
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011818 if (path->fd != -1) {
11819 entry->dir_fd = path->fd;
11820 joined_path = NULL;
11821 }
11822 else {
11823 entry->dir_fd = DEFAULT_DIR_FD;
11824 joined_path = join_path_filename(path->narrow, name, name_len);
11825 if (!joined_path)
11826 goto error;
11827 }
Victor Stinner6036e442015-03-08 01:58:04 +010011828
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030011829 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010011830 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011831 if (joined_path)
11832 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011833 }
11834 else {
11835 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011836 if (joined_path)
11837 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011838 }
11839 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011840 if (!entry->name)
11841 goto error;
11842
11843 if (path->fd != -1) {
11844 entry->path = entry->name;
11845 Py_INCREF(entry->path);
11846 }
11847 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011848 goto error;
11849
Victor Stinner35a97c02015-03-08 02:59:09 +010011850#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011851 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011852#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011853 entry->d_ino = d_ino;
11854
11855 return (PyObject *)entry;
11856
11857error:
11858 Py_XDECREF(entry);
11859 return NULL;
11860}
11861
11862#endif
11863
11864
11865typedef struct {
11866 PyObject_HEAD
11867 path_t path;
11868#ifdef MS_WINDOWS
11869 HANDLE handle;
11870 WIN32_FIND_DATAW file_data;
11871 int first_time;
11872#else /* POSIX */
11873 DIR *dirp;
11874#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011875#ifdef HAVE_FDOPENDIR
11876 int fd;
11877#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011878} ScandirIterator;
11879
11880#ifdef MS_WINDOWS
11881
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011882static int
11883ScandirIterator_is_closed(ScandirIterator *iterator)
11884{
11885 return iterator->handle == INVALID_HANDLE_VALUE;
11886}
11887
Victor Stinner6036e442015-03-08 01:58:04 +010011888static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011889ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011890{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011891 HANDLE handle = iterator->handle;
11892
11893 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011894 return;
11895
Victor Stinner6036e442015-03-08 01:58:04 +010011896 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011897 Py_BEGIN_ALLOW_THREADS
11898 FindClose(handle);
11899 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011900}
11901
11902static PyObject *
11903ScandirIterator_iternext(ScandirIterator *iterator)
11904{
11905 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11906 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011907 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011908
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011909 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011910 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011911 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011912
11913 while (1) {
11914 if (!iterator->first_time) {
11915 Py_BEGIN_ALLOW_THREADS
11916 success = FindNextFileW(iterator->handle, file_data);
11917 Py_END_ALLOW_THREADS
11918 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011919 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011920 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011921 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011922 break;
11923 }
11924 }
11925 iterator->first_time = 0;
11926
11927 /* Skip over . and .. */
11928 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011929 wcscmp(file_data->cFileName, L"..") != 0) {
11930 entry = DirEntry_from_find_data(&iterator->path, file_data);
11931 if (!entry)
11932 break;
11933 return entry;
11934 }
Victor Stinner6036e442015-03-08 01:58:04 +010011935
11936 /* Loop till we get a non-dot directory or finish iterating */
11937 }
11938
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011939 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011940 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011941 return NULL;
11942}
11943
11944#else /* POSIX */
11945
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011946static int
11947ScandirIterator_is_closed(ScandirIterator *iterator)
11948{
11949 return !iterator->dirp;
11950}
11951
Victor Stinner6036e442015-03-08 01:58:04 +010011952static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011953ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011954{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011955 DIR *dirp = iterator->dirp;
11956
11957 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011958 return;
11959
Victor Stinner6036e442015-03-08 01:58:04 +010011960 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011961 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011962#ifdef HAVE_FDOPENDIR
11963 if (iterator->path.fd != -1)
11964 rewinddir(dirp);
11965#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011966 closedir(dirp);
11967 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011968 return;
11969}
11970
11971static PyObject *
11972ScandirIterator_iternext(ScandirIterator *iterator)
11973{
11974 struct dirent *direntp;
11975 Py_ssize_t name_len;
11976 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011977 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011978
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011979 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011980 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011981 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011982
11983 while (1) {
11984 errno = 0;
11985 Py_BEGIN_ALLOW_THREADS
11986 direntp = readdir(iterator->dirp);
11987 Py_END_ALLOW_THREADS
11988
11989 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011990 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011991 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011992 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011993 break;
11994 }
11995
11996 /* Skip over . and .. */
11997 name_len = NAMLEN(direntp);
11998 is_dot = direntp->d_name[0] == '.' &&
11999 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12000 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012001 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012002 name_len, direntp->d_ino
12003#ifdef HAVE_DIRENT_D_TYPE
12004 , direntp->d_type
12005#endif
12006 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012007 if (!entry)
12008 break;
12009 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012010 }
12011
12012 /* Loop till we get a non-dot directory or finish iterating */
12013 }
12014
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012015 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012016 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012017 return NULL;
12018}
12019
12020#endif
12021
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012022static PyObject *
12023ScandirIterator_close(ScandirIterator *self, PyObject *args)
12024{
12025 ScandirIterator_closedir(self);
12026 Py_RETURN_NONE;
12027}
12028
12029static PyObject *
12030ScandirIterator_enter(PyObject *self, PyObject *args)
12031{
12032 Py_INCREF(self);
12033 return self;
12034}
12035
12036static PyObject *
12037ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12038{
12039 ScandirIterator_closedir(self);
12040 Py_RETURN_NONE;
12041}
12042
Victor Stinner6036e442015-03-08 01:58:04 +010012043static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012044ScandirIterator_finalize(ScandirIterator *iterator)
12045{
12046 PyObject *error_type, *error_value, *error_traceback;
12047
12048 /* Save the current exception, if any. */
12049 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12050
12051 if (!ScandirIterator_is_closed(iterator)) {
12052 ScandirIterator_closedir(iterator);
12053
12054 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12055 "unclosed scandir iterator %R", iterator)) {
12056 /* Spurious errors can appear at shutdown */
12057 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12058 PyErr_WriteUnraisable((PyObject *) iterator);
12059 }
12060 }
12061 }
12062
Victor Stinner7bfa4092016-03-23 00:43:54 +010012063 path_cleanup(&iterator->path);
12064
12065 /* Restore the saved exception. */
12066 PyErr_Restore(error_type, error_value, error_traceback);
12067}
12068
12069static void
Victor Stinner6036e442015-03-08 01:58:04 +010012070ScandirIterator_dealloc(ScandirIterator *iterator)
12071{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012072 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12073 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012074
Victor Stinner6036e442015-03-08 01:58:04 +010012075 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12076}
12077
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012078static PyMethodDef ScandirIterator_methods[] = {
12079 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12080 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12081 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12082 {NULL}
12083};
12084
Benjamin Peterson5646de42015-04-12 17:56:34 -040012085static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012086 PyVarObject_HEAD_INIT(NULL, 0)
12087 MODNAME ".ScandirIterator", /* tp_name */
12088 sizeof(ScandirIterator), /* tp_basicsize */
12089 0, /* tp_itemsize */
12090 /* methods */
12091 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12092 0, /* tp_print */
12093 0, /* tp_getattr */
12094 0, /* tp_setattr */
12095 0, /* tp_compare */
12096 0, /* tp_repr */
12097 0, /* tp_as_number */
12098 0, /* tp_as_sequence */
12099 0, /* tp_as_mapping */
12100 0, /* tp_hash */
12101 0, /* tp_call */
12102 0, /* tp_str */
12103 0, /* tp_getattro */
12104 0, /* tp_setattro */
12105 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012106 Py_TPFLAGS_DEFAULT
12107 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012108 0, /* tp_doc */
12109 0, /* tp_traverse */
12110 0, /* tp_clear */
12111 0, /* tp_richcompare */
12112 0, /* tp_weaklistoffset */
12113 PyObject_SelfIter, /* tp_iter */
12114 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012115 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012116 0, /* tp_members */
12117 0, /* tp_getset */
12118 0, /* tp_base */
12119 0, /* tp_dict */
12120 0, /* tp_descr_get */
12121 0, /* tp_descr_set */
12122 0, /* tp_dictoffset */
12123 0, /* tp_init */
12124 0, /* tp_alloc */
12125 0, /* tp_new */
12126 0, /* tp_free */
12127 0, /* tp_is_gc */
12128 0, /* tp_bases */
12129 0, /* tp_mro */
12130 0, /* tp_cache */
12131 0, /* tp_subclasses */
12132 0, /* tp_weaklist */
12133 0, /* tp_del */
12134 0, /* tp_version_tag */
12135 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012136};
12137
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012138/*[clinic input]
12139os.scandir
12140
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012141 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012142
12143Return an iterator of DirEntry objects for given path.
12144
12145path can be specified as either str, bytes or path-like object. If path
12146is bytes, the names of yielded DirEntry objects will also be bytes; in
12147all other circumstances they will be str.
12148
12149If path is None, uses the path='.'.
12150[clinic start generated code]*/
12151
Victor Stinner6036e442015-03-08 01:58:04 +010012152static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012153os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012154/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012155{
12156 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012157#ifdef MS_WINDOWS
12158 wchar_t *path_strW;
12159#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012160 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012161#ifdef HAVE_FDOPENDIR
12162 int fd = -1;
12163#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012164#endif
12165
12166 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12167 if (!iterator)
12168 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012169
12170#ifdef MS_WINDOWS
12171 iterator->handle = INVALID_HANDLE_VALUE;
12172#else
12173 iterator->dirp = NULL;
12174#endif
12175
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012176 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012177 /* Move the ownership to iterator->path */
12178 path->object = NULL;
12179 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012180
12181#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012182 iterator->first_time = 1;
12183
12184 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12185 if (!path_strW)
12186 goto error;
12187
12188 Py_BEGIN_ALLOW_THREADS
12189 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12190 Py_END_ALLOW_THREADS
12191
12192 PyMem_Free(path_strW);
12193
12194 if (iterator->handle == INVALID_HANDLE_VALUE) {
12195 path_error(&iterator->path);
12196 goto error;
12197 }
12198#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012199 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012200#ifdef HAVE_FDOPENDIR
12201 if (path->fd != -1) {
12202 /* closedir() closes the FD, so we duplicate it */
12203 fd = _Py_dup(path->fd);
12204 if (fd == -1)
12205 goto error;
12206
12207 Py_BEGIN_ALLOW_THREADS
12208 iterator->dirp = fdopendir(fd);
12209 Py_END_ALLOW_THREADS
12210 }
12211 else
12212#endif
12213 {
12214 if (iterator->path.narrow)
12215 path_str = iterator->path.narrow;
12216 else
12217 path_str = ".";
12218
12219 Py_BEGIN_ALLOW_THREADS
12220 iterator->dirp = opendir(path_str);
12221 Py_END_ALLOW_THREADS
12222 }
Victor Stinner6036e442015-03-08 01:58:04 +010012223
12224 if (!iterator->dirp) {
12225 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012226#ifdef HAVE_FDOPENDIR
12227 if (fd != -1) {
12228 Py_BEGIN_ALLOW_THREADS
12229 close(fd);
12230 Py_END_ALLOW_THREADS
12231 }
12232#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012233 goto error;
12234 }
12235#endif
12236
12237 return (PyObject *)iterator;
12238
12239error:
12240 Py_DECREF(iterator);
12241 return NULL;
12242}
12243
Ethan Furman410ef8e2016-06-04 12:06:26 -070012244/*
12245 Return the file system path representation of the object.
12246
12247 If the object is str or bytes, then allow it to pass through with
12248 an incremented refcount. If the object defines __fspath__(), then
12249 return the result of that method. All other types raise a TypeError.
12250*/
12251PyObject *
12252PyOS_FSPath(PyObject *path)
12253{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012254 /* For error message reasons, this function is manually inlined in
12255 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012256 _Py_IDENTIFIER(__fspath__);
12257 PyObject *func = NULL;
12258 PyObject *path_repr = NULL;
12259
12260 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12261 Py_INCREF(path);
12262 return path;
12263 }
12264
12265 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12266 if (NULL == func) {
12267 return PyErr_Format(PyExc_TypeError,
12268 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012269 "not %.200s",
12270 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012271 }
12272
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012273 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012274 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012275 if (NULL == path_repr) {
12276 return NULL;
12277 }
12278
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012279 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12280 PyErr_Format(PyExc_TypeError,
12281 "expected %.200s.__fspath__() to return str or bytes, "
12282 "not %.200s", Py_TYPE(path)->tp_name,
12283 Py_TYPE(path_repr)->tp_name);
12284 Py_DECREF(path_repr);
12285 return NULL;
12286 }
12287
Ethan Furman410ef8e2016-06-04 12:06:26 -070012288 return path_repr;
12289}
12290
12291/*[clinic input]
12292os.fspath
12293
12294 path: object
12295
12296Return the file system path representation of the object.
12297
Brett Cannonb4f43e92016-06-09 14:32:08 -070012298If the object is str or bytes, then allow it to pass through as-is. If the
12299object defines __fspath__(), then return the result of that method. All other
12300types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012301[clinic start generated code]*/
12302
12303static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012304os_fspath_impl(PyObject *module, PyObject *path)
12305/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012306{
12307 return PyOS_FSPath(path);
12308}
Victor Stinner6036e442015-03-08 01:58:04 +010012309
Victor Stinner9b1f4742016-09-06 16:18:52 -070012310#ifdef HAVE_GETRANDOM_SYSCALL
12311/*[clinic input]
12312os.getrandom
12313
12314 size: Py_ssize_t
12315 flags: int=0
12316
12317Obtain a series of random bytes.
12318[clinic start generated code]*/
12319
12320static PyObject *
12321os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12322/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12323{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012324 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012325 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012326
12327 if (size < 0) {
12328 errno = EINVAL;
12329 return posix_error();
12330 }
12331
Victor Stinnerec2319c2016-09-20 23:00:59 +020012332 bytes = PyBytes_FromStringAndSize(NULL, size);
12333 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012334 PyErr_NoMemory();
12335 return NULL;
12336 }
12337
12338 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012339 n = syscall(SYS_getrandom,
12340 PyBytes_AS_STRING(bytes),
12341 PyBytes_GET_SIZE(bytes),
12342 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012343 if (n < 0 && errno == EINTR) {
12344 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012345 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012346 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012347
12348 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012349 continue;
12350 }
12351 break;
12352 }
12353
12354 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012355 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012356 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012357 }
12358
Victor Stinnerec2319c2016-09-20 23:00:59 +020012359 if (n != size) {
12360 _PyBytes_Resize(&bytes, n);
12361 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012362
12363 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012364
12365error:
12366 Py_DECREF(bytes);
12367 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012368}
12369#endif /* HAVE_GETRANDOM_SYSCALL */
12370
Larry Hastings31826802013-10-19 00:09:25 -070012371
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012372static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012373
12374 OS_STAT_METHODDEF
12375 OS_ACCESS_METHODDEF
12376 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012377 OS_CHDIR_METHODDEF
12378 OS_CHFLAGS_METHODDEF
12379 OS_CHMOD_METHODDEF
12380 OS_FCHMOD_METHODDEF
12381 OS_LCHMOD_METHODDEF
12382 OS_CHOWN_METHODDEF
12383 OS_FCHOWN_METHODDEF
12384 OS_LCHOWN_METHODDEF
12385 OS_LCHFLAGS_METHODDEF
12386 OS_CHROOT_METHODDEF
12387 OS_CTERMID_METHODDEF
12388 OS_GETCWD_METHODDEF
12389 OS_GETCWDB_METHODDEF
12390 OS_LINK_METHODDEF
12391 OS_LISTDIR_METHODDEF
12392 OS_LSTAT_METHODDEF
12393 OS_MKDIR_METHODDEF
12394 OS_NICE_METHODDEF
12395 OS_GETPRIORITY_METHODDEF
12396 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012397#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012398 {"readlink", (PyCFunction)posix_readlink,
12399 METH_VARARGS | METH_KEYWORDS,
12400 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012401#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012402#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012403 {"readlink", (PyCFunction)win_readlink,
12404 METH_VARARGS | METH_KEYWORDS,
12405 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012406#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012407 OS_RENAME_METHODDEF
12408 OS_REPLACE_METHODDEF
12409 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012410 OS_SYMLINK_METHODDEF
12411 OS_SYSTEM_METHODDEF
12412 OS_UMASK_METHODDEF
12413 OS_UNAME_METHODDEF
12414 OS_UNLINK_METHODDEF
12415 OS_REMOVE_METHODDEF
12416 OS_UTIME_METHODDEF
12417 OS_TIMES_METHODDEF
12418 OS__EXIT_METHODDEF
12419 OS_EXECV_METHODDEF
12420 OS_EXECVE_METHODDEF
12421 OS_SPAWNV_METHODDEF
12422 OS_SPAWNVE_METHODDEF
12423 OS_FORK1_METHODDEF
12424 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012425 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012426 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12427 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12428 OS_SCHED_GETPARAM_METHODDEF
12429 OS_SCHED_GETSCHEDULER_METHODDEF
12430 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12431 OS_SCHED_SETPARAM_METHODDEF
12432 OS_SCHED_SETSCHEDULER_METHODDEF
12433 OS_SCHED_YIELD_METHODDEF
12434 OS_SCHED_SETAFFINITY_METHODDEF
12435 OS_SCHED_GETAFFINITY_METHODDEF
12436 OS_OPENPTY_METHODDEF
12437 OS_FORKPTY_METHODDEF
12438 OS_GETEGID_METHODDEF
12439 OS_GETEUID_METHODDEF
12440 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012441#ifdef HAVE_GETGROUPLIST
12442 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12443#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012444 OS_GETGROUPS_METHODDEF
12445 OS_GETPID_METHODDEF
12446 OS_GETPGRP_METHODDEF
12447 OS_GETPPID_METHODDEF
12448 OS_GETUID_METHODDEF
12449 OS_GETLOGIN_METHODDEF
12450 OS_KILL_METHODDEF
12451 OS_KILLPG_METHODDEF
12452 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012453#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012454 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012455#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012456 OS_SETUID_METHODDEF
12457 OS_SETEUID_METHODDEF
12458 OS_SETREUID_METHODDEF
12459 OS_SETGID_METHODDEF
12460 OS_SETEGID_METHODDEF
12461 OS_SETREGID_METHODDEF
12462 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012463#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012464 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012465#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012466 OS_GETPGID_METHODDEF
12467 OS_SETPGRP_METHODDEF
12468 OS_WAIT_METHODDEF
12469 OS_WAIT3_METHODDEF
12470 OS_WAIT4_METHODDEF
12471 OS_WAITID_METHODDEF
12472 OS_WAITPID_METHODDEF
12473 OS_GETSID_METHODDEF
12474 OS_SETSID_METHODDEF
12475 OS_SETPGID_METHODDEF
12476 OS_TCGETPGRP_METHODDEF
12477 OS_TCSETPGRP_METHODDEF
12478 OS_OPEN_METHODDEF
12479 OS_CLOSE_METHODDEF
12480 OS_CLOSERANGE_METHODDEF
12481 OS_DEVICE_ENCODING_METHODDEF
12482 OS_DUP_METHODDEF
12483 OS_DUP2_METHODDEF
12484 OS_LOCKF_METHODDEF
12485 OS_LSEEK_METHODDEF
12486 OS_READ_METHODDEF
12487 OS_READV_METHODDEF
12488 OS_PREAD_METHODDEF
12489 OS_WRITE_METHODDEF
12490 OS_WRITEV_METHODDEF
12491 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012492#ifdef HAVE_SENDFILE
12493 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12494 posix_sendfile__doc__},
12495#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012496 OS_FSTAT_METHODDEF
12497 OS_ISATTY_METHODDEF
12498 OS_PIPE_METHODDEF
12499 OS_PIPE2_METHODDEF
12500 OS_MKFIFO_METHODDEF
12501 OS_MKNOD_METHODDEF
12502 OS_MAJOR_METHODDEF
12503 OS_MINOR_METHODDEF
12504 OS_MAKEDEV_METHODDEF
12505 OS_FTRUNCATE_METHODDEF
12506 OS_TRUNCATE_METHODDEF
12507 OS_POSIX_FALLOCATE_METHODDEF
12508 OS_POSIX_FADVISE_METHODDEF
12509 OS_PUTENV_METHODDEF
12510 OS_UNSETENV_METHODDEF
12511 OS_STRERROR_METHODDEF
12512 OS_FCHDIR_METHODDEF
12513 OS_FSYNC_METHODDEF
12514 OS_SYNC_METHODDEF
12515 OS_FDATASYNC_METHODDEF
12516 OS_WCOREDUMP_METHODDEF
12517 OS_WIFCONTINUED_METHODDEF
12518 OS_WIFSTOPPED_METHODDEF
12519 OS_WIFSIGNALED_METHODDEF
12520 OS_WIFEXITED_METHODDEF
12521 OS_WEXITSTATUS_METHODDEF
12522 OS_WTERMSIG_METHODDEF
12523 OS_WSTOPSIG_METHODDEF
12524 OS_FSTATVFS_METHODDEF
12525 OS_STATVFS_METHODDEF
12526 OS_CONFSTR_METHODDEF
12527 OS_SYSCONF_METHODDEF
12528 OS_FPATHCONF_METHODDEF
12529 OS_PATHCONF_METHODDEF
12530 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012531 OS__GETFULLPATHNAME_METHODDEF
12532 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012533 OS__GETDISKUSAGE_METHODDEF
12534 OS__GETFINALPATHNAME_METHODDEF
12535 OS__GETVOLUMEPATHNAME_METHODDEF
12536 OS_GETLOADAVG_METHODDEF
12537 OS_URANDOM_METHODDEF
12538 OS_SETRESUID_METHODDEF
12539 OS_SETRESGID_METHODDEF
12540 OS_GETRESUID_METHODDEF
12541 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012542
Larry Hastings2f936352014-08-05 14:04:04 +100012543 OS_GETXATTR_METHODDEF
12544 OS_SETXATTR_METHODDEF
12545 OS_REMOVEXATTR_METHODDEF
12546 OS_LISTXATTR_METHODDEF
12547
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012548#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12549 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12550#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012551 OS_CPU_COUNT_METHODDEF
12552 OS_GET_INHERITABLE_METHODDEF
12553 OS_SET_INHERITABLE_METHODDEF
12554 OS_GET_HANDLE_INHERITABLE_METHODDEF
12555 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012556#ifndef MS_WINDOWS
12557 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12558 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12559#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012560 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012561 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012562 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012563 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012564};
12565
12566
Brian Curtin52173d42010-12-02 18:29:18 +000012567#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012568static int
Brian Curtin52173d42010-12-02 18:29:18 +000012569enable_symlink()
12570{
12571 HANDLE tok;
12572 TOKEN_PRIVILEGES tok_priv;
12573 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012574
12575 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012576 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012577
12578 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012579 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012580
12581 tok_priv.PrivilegeCount = 1;
12582 tok_priv.Privileges[0].Luid = luid;
12583 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12584
12585 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12586 sizeof(TOKEN_PRIVILEGES),
12587 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012588 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012589
Brian Curtin3b4499c2010-12-28 14:31:47 +000012590 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12591 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012592}
12593#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12594
Barry Warsaw4a342091996-12-19 23:50:02 +000012595static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012597{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012598#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012600#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012601#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012603#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012604#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012606#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012607#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012609#endif
Fred Drakec9680921999-12-13 16:37:25 +000012610#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012612#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012613#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012614 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012615#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012616#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012618#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012619#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012620 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012621#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012622#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012623 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012624#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012625#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012626 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012627#endif
12628#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012629 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012630#endif
12631#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012633#endif
12634#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012636#endif
12637#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012639#endif
12640#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012642#endif
12643#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012645#endif
12646#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012648#endif
12649#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012651#endif
12652#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012654#endif
12655#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012657#endif
12658#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012660#endif
12661#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012663#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012664#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012666#endif
12667#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012669#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012670#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012672#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012673#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012675#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012676#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012677#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012679#endif
12680#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012682#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012683#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012684#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012685 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012686#endif
12687#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012689#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012690#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012692#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012693#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012695#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012696#ifdef O_TMPFILE
12697 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12698#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012699#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012701#endif
12702#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012704#endif
12705#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012707#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012708#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012709 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012710#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012711#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012712 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012713#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012714
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012715
Jesus Cea94363612012-06-22 18:32:07 +020012716#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012718#endif
12719#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012721#endif
12722
Tim Peters5aa91602002-01-30 05:46:57 +000012723/* MS Windows */
12724#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012725 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012727#endif
12728#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012729 /* Optimize for short life (keep in memory). */
12730 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012732#endif
12733#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012734 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012736#endif
12737#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012738 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012739 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012740#endif
12741#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012742 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012744#endif
12745
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012746/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012747#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012748 /* Send a SIGIO signal whenever input or output
12749 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012751#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012752#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012753 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012754 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012755#endif
12756#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012757 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012759#endif
12760#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012761 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012763#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012764#ifdef O_NOLINKS
12765 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012767#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012768#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012769 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012771#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012772
Victor Stinner8c62be82010-05-06 00:08:46 +000012773 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012774#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012776#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012777#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012778 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012779#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012780#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012781 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012782#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012783#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012784 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012785#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012786#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012787 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012788#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012789#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012790 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012791#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012792#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012793 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012794#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012795#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012796 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012797#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012798#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012799 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012800#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012801#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012802 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012803#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012804#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012805 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012806#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012807#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012808 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012809#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012810#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012812#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012813#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012814 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012815#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012816#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012817 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012818#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012819#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012820 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012821#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012822#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012823 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012824#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012825
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012826 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012827#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012828 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012829#endif /* ST_RDONLY */
12830#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012831 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012832#endif /* ST_NOSUID */
12833
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012834 /* GNU extensions */
12835#ifdef ST_NODEV
12836 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12837#endif /* ST_NODEV */
12838#ifdef ST_NOEXEC
12839 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12840#endif /* ST_NOEXEC */
12841#ifdef ST_SYNCHRONOUS
12842 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12843#endif /* ST_SYNCHRONOUS */
12844#ifdef ST_MANDLOCK
12845 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12846#endif /* ST_MANDLOCK */
12847#ifdef ST_WRITE
12848 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12849#endif /* ST_WRITE */
12850#ifdef ST_APPEND
12851 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12852#endif /* ST_APPEND */
12853#ifdef ST_NOATIME
12854 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12855#endif /* ST_NOATIME */
12856#ifdef ST_NODIRATIME
12857 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12858#endif /* ST_NODIRATIME */
12859#ifdef ST_RELATIME
12860 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12861#endif /* ST_RELATIME */
12862
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012863 /* FreeBSD sendfile() constants */
12864#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012865 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012866#endif
12867#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012868 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012869#endif
12870#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012871 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012872#endif
12873
Ross Lagerwall7807c352011-03-17 20:20:30 +020012874 /* constants for posix_fadvise */
12875#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012876 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012877#endif
12878#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012880#endif
12881#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012883#endif
12884#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012885 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012886#endif
12887#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012888 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012889#endif
12890#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012891 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012892#endif
12893
12894 /* constants for waitid */
12895#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12897 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12898 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012899#endif
12900#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012901 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012902#endif
12903#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012904 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012905#endif
12906#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012907 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012908#endif
12909#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012910 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012911#endif
12912#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012914#endif
12915#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012916 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012917#endif
12918#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012919 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012920#endif
12921
12922 /* constants for lockf */
12923#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012924 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012925#endif
12926#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012928#endif
12929#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012930 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012931#endif
12932#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012934#endif
12935
Guido van Rossum246bc171999-02-01 23:54:31 +000012936#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012937 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12938 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12939 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12940 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12941 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012942#endif
12943
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012944#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012945#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012947#endif
12948#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012950#endif
12951#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012953#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012954#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080012955 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012956#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012957#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012958 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012959#endif
12960#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012961 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012962#endif
12963#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012964 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012965#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012966#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012967 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012968#endif
12969#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012970 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012971#endif
12972#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012973 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012974#endif
12975#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012976 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012977#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012978#endif
12979
Benjamin Peterson9428d532011-09-14 11:45:52 -040012980#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012981 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12982 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12983 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012984#endif
12985
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012986#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012987 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012988#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012989#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012991#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012992#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012993 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012994#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012995#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012996 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012997#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012998#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012999 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013000#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013001#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013002 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013003#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013004#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013005 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013006#endif
13007
Victor Stinner9b1f4742016-09-06 16:18:52 -070013008#ifdef HAVE_GETRANDOM_SYSCALL
13009 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13010 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13011#endif
13012
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013014}
13015
13016
Martin v. Löwis1a214512008-06-11 05:26:20 +000013017static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013018 PyModuleDef_HEAD_INIT,
13019 MODNAME,
13020 posix__doc__,
13021 -1,
13022 posix_methods,
13023 NULL,
13024 NULL,
13025 NULL,
13026 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013027};
13028
13029
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013030static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013031
13032#ifdef HAVE_FACCESSAT
13033 "HAVE_FACCESSAT",
13034#endif
13035
13036#ifdef HAVE_FCHDIR
13037 "HAVE_FCHDIR",
13038#endif
13039
13040#ifdef HAVE_FCHMOD
13041 "HAVE_FCHMOD",
13042#endif
13043
13044#ifdef HAVE_FCHMODAT
13045 "HAVE_FCHMODAT",
13046#endif
13047
13048#ifdef HAVE_FCHOWN
13049 "HAVE_FCHOWN",
13050#endif
13051
Larry Hastings00964ed2013-08-12 13:49:30 -040013052#ifdef HAVE_FCHOWNAT
13053 "HAVE_FCHOWNAT",
13054#endif
13055
Larry Hastings9cf065c2012-06-22 16:30:09 -070013056#ifdef HAVE_FEXECVE
13057 "HAVE_FEXECVE",
13058#endif
13059
13060#ifdef HAVE_FDOPENDIR
13061 "HAVE_FDOPENDIR",
13062#endif
13063
Georg Brandl306336b2012-06-24 12:55:33 +020013064#ifdef HAVE_FPATHCONF
13065 "HAVE_FPATHCONF",
13066#endif
13067
Larry Hastings9cf065c2012-06-22 16:30:09 -070013068#ifdef HAVE_FSTATAT
13069 "HAVE_FSTATAT",
13070#endif
13071
13072#ifdef HAVE_FSTATVFS
13073 "HAVE_FSTATVFS",
13074#endif
13075
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013076#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013077 "HAVE_FTRUNCATE",
13078#endif
13079
Larry Hastings9cf065c2012-06-22 16:30:09 -070013080#ifdef HAVE_FUTIMENS
13081 "HAVE_FUTIMENS",
13082#endif
13083
13084#ifdef HAVE_FUTIMES
13085 "HAVE_FUTIMES",
13086#endif
13087
13088#ifdef HAVE_FUTIMESAT
13089 "HAVE_FUTIMESAT",
13090#endif
13091
13092#ifdef HAVE_LINKAT
13093 "HAVE_LINKAT",
13094#endif
13095
13096#ifdef HAVE_LCHFLAGS
13097 "HAVE_LCHFLAGS",
13098#endif
13099
13100#ifdef HAVE_LCHMOD
13101 "HAVE_LCHMOD",
13102#endif
13103
13104#ifdef HAVE_LCHOWN
13105 "HAVE_LCHOWN",
13106#endif
13107
13108#ifdef HAVE_LSTAT
13109 "HAVE_LSTAT",
13110#endif
13111
13112#ifdef HAVE_LUTIMES
13113 "HAVE_LUTIMES",
13114#endif
13115
13116#ifdef HAVE_MKDIRAT
13117 "HAVE_MKDIRAT",
13118#endif
13119
13120#ifdef HAVE_MKFIFOAT
13121 "HAVE_MKFIFOAT",
13122#endif
13123
13124#ifdef HAVE_MKNODAT
13125 "HAVE_MKNODAT",
13126#endif
13127
13128#ifdef HAVE_OPENAT
13129 "HAVE_OPENAT",
13130#endif
13131
13132#ifdef HAVE_READLINKAT
13133 "HAVE_READLINKAT",
13134#endif
13135
13136#ifdef HAVE_RENAMEAT
13137 "HAVE_RENAMEAT",
13138#endif
13139
13140#ifdef HAVE_SYMLINKAT
13141 "HAVE_SYMLINKAT",
13142#endif
13143
13144#ifdef HAVE_UNLINKAT
13145 "HAVE_UNLINKAT",
13146#endif
13147
13148#ifdef HAVE_UTIMENSAT
13149 "HAVE_UTIMENSAT",
13150#endif
13151
13152#ifdef MS_WINDOWS
13153 "MS_WINDOWS",
13154#endif
13155
13156 NULL
13157};
13158
13159
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013160PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013161INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013162{
Victor Stinner8c62be82010-05-06 00:08:46 +000013163 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013164 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013165 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013166
Brian Curtin52173d42010-12-02 18:29:18 +000013167#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013168 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013169#endif
13170
Victor Stinner8c62be82010-05-06 00:08:46 +000013171 m = PyModule_Create(&posixmodule);
13172 if (m == NULL)
13173 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013174
Victor Stinner8c62be82010-05-06 00:08:46 +000013175 /* Initialize environ dictionary */
13176 v = convertenviron();
13177 Py_XINCREF(v);
13178 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13179 return NULL;
13180 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013181
Victor Stinner8c62be82010-05-06 00:08:46 +000013182 if (all_ins(m))
13183 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013184
Victor Stinner8c62be82010-05-06 00:08:46 +000013185 if (setup_confname_tables(m))
13186 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013187
Victor Stinner8c62be82010-05-06 00:08:46 +000013188 Py_INCREF(PyExc_OSError);
13189 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013190
Guido van Rossumb3d39562000-01-31 18:41:26 +000013191#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013192 if (posix_putenv_garbage == NULL)
13193 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013194#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013195
Victor Stinner8c62be82010-05-06 00:08:46 +000013196 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013197#if defined(HAVE_WAITID) && !defined(__APPLE__)
13198 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013199 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13200 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013201#endif
13202
Christian Heimes25827622013-10-12 01:27:08 +020013203 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013204 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13205 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13206 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013207 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13208 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013209 structseq_new = StatResultType.tp_new;
13210 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013211
Christian Heimes25827622013-10-12 01:27:08 +020013212 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013213 if (PyStructSequence_InitType2(&StatVFSResultType,
13214 &statvfs_result_desc) < 0)
13215 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013216#ifdef NEED_TICKS_PER_SECOND
13217# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013218 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013219# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013220 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013221# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013222 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013223# endif
13224#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013225
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013226#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013227 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013228 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13229 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013230 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013231#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013232
13233 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013234 if (PyStructSequence_InitType2(&TerminalSizeType,
13235 &TerminalSize_desc) < 0)
13236 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013237
13238 /* initialize scandir types */
13239 if (PyType_Ready(&ScandirIteratorType) < 0)
13240 return NULL;
13241 if (PyType_Ready(&DirEntryType) < 0)
13242 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013243 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013244#if defined(HAVE_WAITID) && !defined(__APPLE__)
13245 Py_INCREF((PyObject*) &WaitidResultType);
13246 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13247#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013248 Py_INCREF((PyObject*) &StatResultType);
13249 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13250 Py_INCREF((PyObject*) &StatVFSResultType);
13251 PyModule_AddObject(m, "statvfs_result",
13252 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013253
13254#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013255 Py_INCREF(&SchedParamType);
13256 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013257#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013258
Larry Hastings605a62d2012-06-24 04:33:36 -070013259 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013260 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13261 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013262 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13263
13264 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013265 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13266 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013267 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13268
Thomas Wouters477c8d52006-05-27 19:21:47 +000013269#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013270 /*
13271 * Step 2 of weak-linking support on Mac OS X.
13272 *
13273 * The code below removes functions that are not available on the
13274 * currently active platform.
13275 *
13276 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013277 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013278 * OSX 10.4.
13279 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013280#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013281 if (fstatvfs == NULL) {
13282 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13283 return NULL;
13284 }
13285 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013286#endif /* HAVE_FSTATVFS */
13287
13288#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013289 if (statvfs == NULL) {
13290 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13291 return NULL;
13292 }
13293 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013294#endif /* HAVE_STATVFS */
13295
13296# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013297 if (lchown == NULL) {
13298 if (PyObject_DelAttrString(m, "lchown") == -1) {
13299 return NULL;
13300 }
13301 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013302#endif /* HAVE_LCHOWN */
13303
13304
13305#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013306
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013307 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013308 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13309
Larry Hastings6fe20b32012-04-19 15:07:49 -070013310 billion = PyLong_FromLong(1000000000);
13311 if (!billion)
13312 return NULL;
13313
Larry Hastings9cf065c2012-06-22 16:30:09 -070013314 /* suppress "function not used" warnings */
13315 {
13316 int ignored;
13317 fd_specified("", -1);
13318 follow_symlinks_specified("", 1);
13319 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13320 dir_fd_converter(Py_None, &ignored);
13321 dir_fd_unavailable(Py_None, &ignored);
13322 }
13323
13324 /*
13325 * provide list of locally available functions
13326 * so os.py can populate support_* lists
13327 */
13328 list = PyList_New(0);
13329 if (!list)
13330 return NULL;
13331 for (trace = have_functions; *trace; trace++) {
13332 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13333 if (!unicode)
13334 return NULL;
13335 if (PyList_Append(list, unicode))
13336 return NULL;
13337 Py_DECREF(unicode);
13338 }
13339 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013340
13341 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013342 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013343
13344 initialized = 1;
13345
Victor Stinner8c62be82010-05-06 00:08:46 +000013346 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013347}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013348
13349#ifdef __cplusplus
13350}
13351#endif