blob: be8a66dd5028e8f0567ad36289911fe7276d487d [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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif /* HAVE_SYS_TYPES_H */
62
63#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000066
Guido van Rossum36bc6801995-06-14 22:54:23 +000067#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000068#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000069#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000070
Thomas Wouters0e3f5912006-08-11 14:57:12 +000071#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000072#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000074
Guido van Rossumb6775db1994-08-01 11:34:53 +000075#ifdef HAVE_FCNTL_H
76#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000077#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Guido van Rossuma6535fd2001-10-18 19:44:10 +000079#ifdef HAVE_GRP_H
80#include <grp.h>
81#endif
82
Barry Warsaw5676bd12003-01-07 20:57:09 +000083#ifdef HAVE_SYSEXITS_H
84#include <sysexits.h>
85#endif /* HAVE_SYSEXITS_H */
86
Anthony Baxter8a560de2004-10-13 15:30:56 +000087#ifdef HAVE_SYS_LOADAVG_H
88#include <sys/loadavg.h>
89#endif
90
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000091#ifdef HAVE_SYS_SENDFILE_H
92#include <sys/sendfile.h>
93#endif
94
Benjamin Peterson94b580d2011-08-02 17:30:04 -050095#ifdef HAVE_SCHED_H
96#include <sched.h>
97#endif
98
Benjamin Peterson2dbda072012-03-16 10:12:55 -050099#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500100#undef HAVE_SCHED_SETAFFINITY
101#endif
102
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200103#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400104#define USE_XATTRS
105#endif
106
107#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400108#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400109#endif
110
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000111#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
112#ifdef HAVE_SYS_SOCKET_H
113#include <sys/socket.h>
114#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000115#endif
116
Victor Stinner8b905bd2011-10-25 13:34:04 +0200117#ifdef HAVE_DLFCN_H
118#include <dlfcn.h>
119#endif
120
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200121#ifdef __hpux
122#include <sys/mpctl.h>
123#endif
124
125#if defined(__DragonFly__) || \
126 defined(__OpenBSD__) || \
127 defined(__FreeBSD__) || \
128 defined(__NetBSD__) || \
129 defined(__APPLE__)
130#include <sys/sysctl.h>
131#endif
132
Victor Stinner9b1f4742016-09-06 16:18:52 -0700133#ifdef HAVE_LINUX_RANDOM_H
134# include <linux/random.h>
135#endif
136#ifdef HAVE_GETRANDOM_SYSCALL
137# include <sys/syscall.h>
138#endif
139
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100140#if defined(MS_WINDOWS)
141# define TERMSIZE_USE_CONIO
142#elif defined(HAVE_SYS_IOCTL_H)
143# include <sys/ioctl.h>
144# if defined(HAVE_TERMIOS_H)
145# include <termios.h>
146# endif
147# if defined(TIOCGWINSZ)
148# define TERMSIZE_USE_IOCTL
149# endif
150#endif /* MS_WINDOWS */
151
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000153/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000156#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000160#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000161#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000163#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700164#define HAVE_WSPAWNV 1
165#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SYSTEM 1
168#define HAVE_CWAIT 1
169#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000170#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000171#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172/* Unix functions that the configure script doesn't check for */
173#define HAVE_EXECV 1
174#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000175#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000176#define HAVE_FORK1 1
177#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#define HAVE_GETEGID 1
179#define HAVE_GETEUID 1
180#define HAVE_GETGID 1
181#define HAVE_GETPPID 1
182#define HAVE_GETUID 1
183#define HAVE_KILL 1
184#define HAVE_OPENDIR 1
185#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000186#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000189#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000190#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000191
Victor Stinnera2f7c002012-02-08 03:36:25 +0100192
Larry Hastings61272b72014-01-07 12:41:53 -0800193/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000194# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800195module os
Larry Hastings61272b72014-01-07 12:41:53 -0800196[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000197/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100198
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000200
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000201#if defined(__sgi)&&_COMPILER_VERSION>=700
202/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
203 (default) */
204extern char *ctermid_r(char *);
205#endif
206
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000207#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000208#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000211#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000216#endif
217#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chdir(char *);
219extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chdir(const char *);
222extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000225/*#ifdef HAVE_FCHMOD
226extern int fchmod(int, mode_t);
227#endif*/
228/*#ifdef HAVE_LCHMOD
229extern int lchmod(const char *, mode_t);
230#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chown(const char *, uid_t, gid_t);
232extern char *getcwd(char *, int);
233extern char *strerror(int);
234extern int link(const char *, const char *);
235extern int rename(const char *, const char *);
236extern int stat(const char *, struct stat *);
237extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000239extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000240#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000243#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000245
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000246#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#ifdef HAVE_UTIME_H
249#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000252#ifdef HAVE_SYS_UTIME_H
253#include <sys/utime.h>
254#define HAVE_UTIME_H /* pretend we do for the rest of this file */
255#endif /* HAVE_SYS_UTIME_H */
256
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#ifdef HAVE_SYS_TIMES_H
258#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
261#ifdef HAVE_SYS_PARAM_H
262#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000263#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264
265#ifdef HAVE_SYS_UTSNAME_H
266#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#define NAMLEN(dirent) strlen((dirent)->d_name)
272#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000273#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#include <direct.h>
275#define NAMLEN(dirent) strlen((dirent)->d_name)
276#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
295#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
304#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100310#ifndef IO_REPARSE_TAG_MOUNT_POINT
311#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
312#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000313#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000314#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000315#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000316#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000317#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000318#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
319#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000320static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000321#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000322#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000323
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#if defined(PATH_MAX) && PATH_MAX > 1024
326#define MAXPATHLEN PATH_MAX
327#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000328#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000330#endif /* MAXPATHLEN */
331
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000332#ifdef UNION_WAIT
333/* Emulate some macros on systems that have a union instead of macros */
334
335#ifndef WIFEXITED
336#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
337#endif
338
339#ifndef WEXITSTATUS
340#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
341#endif
342
343#ifndef WTERMSIG
344#define WTERMSIG(u_wait) ((u_wait).w_termsig)
345#endif
346
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000347#define WAIT_TYPE union wait
348#define WAIT_STATUS_INT(s) (s.w_status)
349
350#else /* !UNION_WAIT */
351#define WAIT_TYPE int
352#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000353#endif /* UNION_WAIT */
354
Greg Wardb48bc172000-03-01 21:51:56 +0000355/* Don't use the "_r" form if we don't need it (also, won't have a
356 prototype for it, at least on Solaris -- maybe others as well?). */
357#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
358#define USE_CTERMID_R
359#endif
360
Fred Drake699f3522000-06-29 21:12:41 +0000361/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000362#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000363#undef FSTAT
364#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200365#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200368# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800369# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000370#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000371# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700372# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000373# define FSTAT fstat
374# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000375#endif
376
Tim Peters11b23062003-04-23 02:39:17 +0000377#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000378#include <sys/mkdev.h>
379#else
380#if defined(MAJOR_IN_SYSMACROS)
381#include <sys/sysmacros.h>
382#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000383#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
384#include <sys/mkdev.h>
385#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000386#endif
Fred Drake699f3522000-06-29 21:12:41 +0000387
Victor Stinner6edddfa2013-11-24 19:22:57 +0100388#define DWORD_MAX 4294967295U
389
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200390#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100391#define INITFUNC PyInit_nt
392#define MODNAME "nt"
393#else
394#define INITFUNC PyInit_posix
395#define MODNAME "posix"
396#endif
397
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200398
399#ifdef HAVE_FORK
400static void
401run_at_forkers(PyObject *lst, int reverse)
402{
403 Py_ssize_t i;
404 PyObject *cpy;
405
406 if (lst != NULL) {
407 assert(PyList_CheckExact(lst));
408
409 /* Use a list copy in case register_at_fork() is called from
410 * one of the callbacks.
411 */
412 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
413 if (cpy == NULL)
414 PyErr_WriteUnraisable(lst);
415 else {
416 if (reverse)
417 PyList_Reverse(cpy);
418 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
419 PyObject *func, *res;
420 func = PyList_GET_ITEM(cpy, i);
421 res = PyObject_CallObject(func, NULL);
422 if (res == NULL)
423 PyErr_WriteUnraisable(func);
424 else
425 Py_DECREF(res);
426 }
427 Py_DECREF(cpy);
428 }
429 }
430}
431
432void
433PyOS_BeforeFork(void)
434{
435 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
436
437 _PyImport_AcquireLock();
438}
439
440void
441PyOS_AfterFork_Parent(void)
442{
443 if (_PyImport_ReleaseLock() <= 0)
444 Py_FatalError("failed releasing import lock after fork");
445
446 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
447}
448
449void
450PyOS_AfterFork_Child(void)
451{
452#ifdef WITH_THREAD
453 /* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
454 * can be called safely. */
455 PyThread_ReInitTLS();
456 _PyGILState_Reinit();
457 PyEval_ReInitThreads();
458 _PyImport_ReInitLock();
459#endif
460 _PySignal_AfterFork();
461
462 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
463}
464
465static int
466register_at_forker(PyObject **lst, PyObject *func)
467{
468 if (*lst == NULL) {
469 *lst = PyList_New(0);
470 if (*lst == NULL)
471 return -1;
472 }
473 return PyList_Append(*lst, func);
474}
475#endif
476
477/* Legacy wrapper */
478void
479PyOS_AfterFork(void)
480{
481#ifdef HAVE_FORK
482 PyOS_AfterFork_Child();
483#endif
484}
485
486
Victor Stinner6036e442015-03-08 01:58:04 +0100487#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200488/* defined in fileutils.c */
489PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
490PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
491 ULONG, struct _Py_stat_struct *);
492#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700493
494#ifdef MS_WINDOWS
495static int
496win32_warn_bytes_api()
497{
498 return PyErr_WarnEx(PyExc_DeprecationWarning,
499 "The Windows bytes API has been deprecated, "
500 "use Unicode filenames instead",
501 1);
502}
503#endif
504
505
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200506#ifndef MS_WINDOWS
507PyObject *
508_PyLong_FromUid(uid_t uid)
509{
510 if (uid == (uid_t)-1)
511 return PyLong_FromLong(-1);
512 return PyLong_FromUnsignedLong(uid);
513}
514
515PyObject *
516_PyLong_FromGid(gid_t gid)
517{
518 if (gid == (gid_t)-1)
519 return PyLong_FromLong(-1);
520 return PyLong_FromUnsignedLong(gid);
521}
522
523int
524_Py_Uid_Converter(PyObject *obj, void *p)
525{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 uid_t uid;
527 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200528 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200529 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 unsigned long uresult;
531
532 index = PyNumber_Index(obj);
533 if (index == NULL) {
534 PyErr_Format(PyExc_TypeError,
535 "uid should be integer, not %.200s",
536 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200537 return 0;
538 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700539
540 /*
541 * Handling uid_t is complicated for two reasons:
542 * * Although uid_t is (always?) unsigned, it still
543 * accepts -1.
544 * * We don't know its size in advance--it may be
545 * bigger than an int, or it may be smaller than
546 * a long.
547 *
548 * So a bit of defensive programming is in order.
549 * Start with interpreting the value passed
550 * in as a signed long and see if it works.
551 */
552
553 result = PyLong_AsLongAndOverflow(index, &overflow);
554
555 if (!overflow) {
556 uid = (uid_t)result;
557
558 if (result == -1) {
559 if (PyErr_Occurred())
560 goto fail;
561 /* It's a legitimate -1, we're done. */
562 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200563 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700564
565 /* Any other negative number is disallowed. */
566 if (result < 0)
567 goto underflow;
568
569 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200570 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700571 (long)uid != result)
572 goto underflow;
573 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575
576 if (overflow < 0)
577 goto underflow;
578
579 /*
580 * Okay, the value overflowed a signed long. If it
581 * fits in an *unsigned* long, it may still be okay,
582 * as uid_t may be unsigned long on this platform.
583 */
584 uresult = PyLong_AsUnsignedLong(index);
585 if (PyErr_Occurred()) {
586 if (PyErr_ExceptionMatches(PyExc_OverflowError))
587 goto overflow;
588 goto fail;
589 }
590
591 uid = (uid_t)uresult;
592
593 /*
594 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
595 * but this value would get interpreted as (uid_t)-1 by chown
596 * and its siblings. That's not what the user meant! So we
597 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100598 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700599 */
600 if (uid == (uid_t)-1)
601 goto overflow;
602
603 /* Ensure the value wasn't truncated. */
604 if (sizeof(uid_t) < sizeof(long) &&
605 (unsigned long)uid != uresult)
606 goto overflow;
607 /* fallthrough */
608
609success:
610 Py_DECREF(index);
611 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200612 return 1;
613
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200615 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616 "uid is less than minimum");
617 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700619overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700621 "uid is greater than maximum");
622 /* fallthrough */
623
624fail:
625 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200626 return 0;
627}
628
629int
630_Py_Gid_Converter(PyObject *obj, void *p)
631{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700632 gid_t gid;
633 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200634 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200635 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700636 unsigned long uresult;
637
638 index = PyNumber_Index(obj);
639 if (index == NULL) {
640 PyErr_Format(PyExc_TypeError,
641 "gid should be integer, not %.200s",
642 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200643 return 0;
644 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700645
646 /*
647 * Handling gid_t is complicated for two reasons:
648 * * Although gid_t is (always?) unsigned, it still
649 * accepts -1.
650 * * We don't know its size in advance--it may be
651 * bigger than an int, or it may be smaller than
652 * a long.
653 *
654 * So a bit of defensive programming is in order.
655 * Start with interpreting the value passed
656 * in as a signed long and see if it works.
657 */
658
659 result = PyLong_AsLongAndOverflow(index, &overflow);
660
661 if (!overflow) {
662 gid = (gid_t)result;
663
664 if (result == -1) {
665 if (PyErr_Occurred())
666 goto fail;
667 /* It's a legitimate -1, we're done. */
668 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200669 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700670
671 /* Any other negative number is disallowed. */
672 if (result < 0) {
673 goto underflow;
674 }
675
676 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200677 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700678 (long)gid != result)
679 goto underflow;
680 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200681 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700682
683 if (overflow < 0)
684 goto underflow;
685
686 /*
687 * Okay, the value overflowed a signed long. If it
688 * fits in an *unsigned* long, it may still be okay,
689 * as gid_t may be unsigned long on this platform.
690 */
691 uresult = PyLong_AsUnsignedLong(index);
692 if (PyErr_Occurred()) {
693 if (PyErr_ExceptionMatches(PyExc_OverflowError))
694 goto overflow;
695 goto fail;
696 }
697
698 gid = (gid_t)uresult;
699
700 /*
701 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
702 * but this value would get interpreted as (gid_t)-1 by chown
703 * and its siblings. That's not what the user meant! So we
704 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100705 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700706 */
707 if (gid == (gid_t)-1)
708 goto overflow;
709
710 /* Ensure the value wasn't truncated. */
711 if (sizeof(gid_t) < sizeof(long) &&
712 (unsigned long)gid != uresult)
713 goto overflow;
714 /* fallthrough */
715
716success:
717 Py_DECREF(index);
718 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200719 return 1;
720
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700721underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200722 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723 "gid is less than minimum");
724 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200725
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700726overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700728 "gid is greater than maximum");
729 /* fallthrough */
730
731fail:
732 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200733 return 0;
734}
735#endif /* MS_WINDOWS */
736
737
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700738#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800739
740
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200741#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
742static int
743_Py_Dev_Converter(PyObject *obj, void *p)
744{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200745 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200746 if (PyErr_Occurred())
747 return 0;
748 return 1;
749}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800750#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200751
752
Larry Hastings9cf065c2012-06-22 16:30:09 -0700753#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400754/*
755 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
756 * without the int cast, the value gets interpreted as uint (4291925331),
757 * which doesn't play nicely with all the initializer lines in this file that
758 * look like this:
759 * int dir_fd = DEFAULT_DIR_FD;
760 */
761#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700762#else
763#define DEFAULT_DIR_FD (-100)
764#endif
765
766static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300767_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200768{
769 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700770 long long_value;
771
772 PyObject *index = PyNumber_Index(o);
773 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700774 return 0;
775 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700776
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300777 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778 long_value = PyLong_AsLongAndOverflow(index, &overflow);
779 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300780 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200781 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700782 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700783 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 return 0;
785 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200786 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700787 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700788 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 return 0;
790 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700791
Larry Hastings9cf065c2012-06-22 16:30:09 -0700792 *p = (int)long_value;
793 return 1;
794}
795
796static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200797dir_fd_converter(PyObject *o, void *p)
798{
799 if (o == Py_None) {
800 *(int *)p = DEFAULT_DIR_FD;
801 return 1;
802 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300803 else if (PyIndex_Check(o)) {
804 return _fd_converter(o, (int *)p);
805 }
806 else {
807 PyErr_Format(PyExc_TypeError,
808 "argument should be integer or None, not %.200s",
809 Py_TYPE(o)->tp_name);
810 return 0;
811 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700812}
813
814
Larry Hastings9cf065c2012-06-22 16:30:09 -0700815/*
816 * A PyArg_ParseTuple "converter" function
817 * that handles filesystem paths in the manner
818 * preferred by the os module.
819 *
820 * path_converter accepts (Unicode) strings and their
821 * subclasses, and bytes and their subclasses. What
822 * it does with the argument depends on the platform:
823 *
824 * * On Windows, if we get a (Unicode) string we
825 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700826 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700827 *
828 * * On all other platforms, strings are encoded
829 * to bytes using PyUnicode_FSConverter, then we
830 * extract the char * from the bytes object and
831 * return that.
832 *
833 * path_converter also optionally accepts signed
834 * integers (representing open file descriptors) instead
835 * of path strings.
836 *
837 * Input fields:
838 * path.nullable
839 * If nonzero, the path is permitted to be None.
840 * path.allow_fd
841 * If nonzero, the path is permitted to be a file handle
842 * (a signed int) instead of a string.
843 * path.function_name
844 * If non-NULL, path_converter will use that as the name
845 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700846 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700847 * path.argument_name
848 * If non-NULL, path_converter will use that as the name
849 * of the parameter in error messages.
850 * (If path.argument_name is NULL it uses "path".)
851 *
852 * Output fields:
853 * path.wide
854 * Points to the path if it was expressed as Unicode
855 * and was not encoded. (Only used on Windows.)
856 * path.narrow
857 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700858 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000859 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700860 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700861 * path.fd
862 * Contains a file descriptor if path.accept_fd was true
863 * and the caller provided a signed integer instead of any
864 * sort of string.
865 *
866 * WARNING: if your "path" parameter is optional, and is
867 * unspecified, path_converter will never get called.
868 * So if you set allow_fd, you *MUST* initialize path.fd = -1
869 * yourself!
870 * path.length
871 * The length of the path in characters, if specified as
872 * a string.
873 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800874 * The original object passed in (if get a PathLike object,
875 * the result of PyOS_FSPath() is treated as the original object).
876 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700877 * path.cleanup
878 * For internal use only. May point to a temporary object.
879 * (Pay no attention to the man behind the curtain.)
880 *
881 * At most one of path.wide or path.narrow will be non-NULL.
882 * If path was None and path.nullable was set,
883 * or if path was an integer and path.allow_fd was set,
884 * both path.wide and path.narrow will be NULL
885 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200886 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700887 * path_converter takes care to not write to the path_t
888 * unless it's successful. However it must reset the
889 * "cleanup" field each time it's called.
890 *
891 * Use as follows:
892 * path_t path;
893 * memset(&path, 0, sizeof(path));
894 * PyArg_ParseTuple(args, "O&", path_converter, &path);
895 * // ... use values from path ...
896 * path_cleanup(&path);
897 *
898 * (Note that if PyArg_Parse fails you don't need to call
899 * path_cleanup(). However it is safe to do so.)
900 */
901typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100902 const char *function_name;
903 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700904 int nullable;
905 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300906 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700907#ifdef MS_WINDOWS
908 BOOL narrow;
909#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300910 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700911#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700912 int fd;
913 Py_ssize_t length;
914 PyObject *object;
915 PyObject *cleanup;
916} path_t;
917
Steve Dowercc16be82016-09-08 10:35:16 -0700918#ifdef MS_WINDOWS
919#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
920 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
921#else
Larry Hastings2f936352014-08-05 14:04:04 +1000922#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
923 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700924#endif
Larry Hastings31826802013-10-19 00:09:25 -0700925
Larry Hastings9cf065c2012-06-22 16:30:09 -0700926static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800927path_cleanup(path_t *path)
928{
929 Py_CLEAR(path->object);
930 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931}
932
933static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300934path_converter(PyObject *o, void *p)
935{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700936 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800937 PyObject *bytes = NULL;
938 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700939 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300940 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700941#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800942 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700943 const wchar_t *wide;
944#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945
946#define FORMAT_EXCEPTION(exc, fmt) \
947 PyErr_Format(exc, "%s%s" fmt, \
948 path->function_name ? path->function_name : "", \
949 path->function_name ? ": " : "", \
950 path->argument_name ? path->argument_name : "path")
951
952 /* Py_CLEANUP_SUPPORTED support */
953 if (o == NULL) {
954 path_cleanup(path);
955 return 1;
956 }
957
Brett Cannon3f9183b2016-08-26 14:44:48 -0700958 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800959 path->object = path->cleanup = NULL;
960 /* path->object owns a reference to the original object */
961 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300963 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700965#ifdef MS_WINDOWS
966 path->narrow = FALSE;
967#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700969#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700970 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800971 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700972 }
973
Brett Cannon3f9183b2016-08-26 14:44:48 -0700974 /* Only call this here so that we don't treat the return value of
975 os.fspath() as an fd or buffer. */
976 is_index = path->allow_fd && PyIndex_Check(o);
977 is_buffer = PyObject_CheckBuffer(o);
978 is_bytes = PyBytes_Check(o);
979 is_unicode = PyUnicode_Check(o);
980
981 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
982 /* Inline PyOS_FSPath() for better error messages. */
983 _Py_IDENTIFIER(__fspath__);
984 PyObject *func = NULL;
985
986 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
987 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800988 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700989 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800990 /* still owns a reference to the original object */
991 Py_DECREF(o);
992 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700993 Py_DECREF(func);
994 if (NULL == o) {
995 goto error_exit;
996 }
997 else if (PyUnicode_Check(o)) {
998 is_unicode = 1;
999 }
1000 else if (PyBytes_Check(o)) {
1001 is_bytes = 1;
1002 }
1003 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001004 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001005 }
1006 }
1007
1008 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001009#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001010 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001011 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001012 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001013 }
Victor Stinner59799a82013-11-13 14:17:30 +01001014 if (length > 32767) {
1015 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001016 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001017 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001018 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001019 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001021 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001022
1023 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001024 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001026 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001028 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001029 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001030 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001031#endif
1032 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001033 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001034 bytes = o;
1035 Py_INCREF(bytes);
1036 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001037 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001038 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1039 "%s%s%s should be %s, not %.200s",
1040 path->function_name ? path->function_name : "",
1041 path->function_name ? ": " : "",
1042 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1044 "integer or None" :
1045 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1046 path->nullable ? "string, bytes, os.PathLike or None" :
1047 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001050 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001051 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001053 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 }
1055 }
Steve Dowercc16be82016-09-08 10:35:16 -07001056 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001057 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001058 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001059 }
1060 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001061#ifdef MS_WINDOWS
1062 path->narrow = FALSE;
1063#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001064 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001065#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001066 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001067 }
1068 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001069 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001070 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1071 path->function_name ? path->function_name : "",
1072 path->function_name ? ": " : "",
1073 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001074 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1075 "integer or None" :
1076 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1077 path->nullable ? "string, bytes, os.PathLike or None" :
1078 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001079 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001080 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 }
1082
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001085 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001086 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001087 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001088 }
1089
Steve Dowercc16be82016-09-08 10:35:16 -07001090#ifdef MS_WINDOWS
1091 wo = PyUnicode_DecodeFSDefaultAndSize(
1092 narrow,
1093 length
1094 );
1095 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001096 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001097 }
1098
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001100 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001102 }
1103 if (length > 32767) {
1104 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 if (wcslen(wide) != length) {
1108 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001110 }
1111 path->wide = wide;
1112 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001113 path->cleanup = wo;
1114 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001115#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001116 path->wide = NULL;
1117 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001118 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 /* Still a reference owned by path->object, don't have to
1120 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001122 }
1123 else {
1124 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001125 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001126#endif
1127 path->fd = -1;
1128
1129 success_exit:
1130 path->length = length;
1131 path->object = o;
1132 return Py_CLEANUP_SUPPORTED;
1133
1134 error_exit:
1135 Py_XDECREF(o);
1136 Py_XDECREF(bytes);
1137#ifdef MS_WINDOWS
1138 Py_XDECREF(wo);
1139#endif
1140 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141}
1142
1143static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001144argument_unavailable_error(const char *function_name, const char *argument_name)
1145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 PyErr_Format(PyExc_NotImplementedError,
1147 "%s%s%s unavailable on this platform",
1148 (function_name != NULL) ? function_name : "",
1149 (function_name != NULL) ? ": ": "",
1150 argument_name);
1151}
1152
1153static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001154dir_fd_unavailable(PyObject *o, void *p)
1155{
1156 int dir_fd;
1157 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001158 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001159 if (dir_fd != DEFAULT_DIR_FD) {
1160 argument_unavailable_error(NULL, "dir_fd");
1161 return 0;
1162 }
1163 *(int *)p = dir_fd;
1164 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165}
1166
1167static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001168fd_specified(const char *function_name, int fd)
1169{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 if (fd == -1)
1171 return 0;
1172
1173 argument_unavailable_error(function_name, "fd");
1174 return 1;
1175}
1176
1177static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001178follow_symlinks_specified(const char *function_name, int follow_symlinks)
1179{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001180 if (follow_symlinks)
1181 return 0;
1182
1183 argument_unavailable_error(function_name, "follow_symlinks");
1184 return 1;
1185}
1186
1187static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001188path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1189{
Steve Dowercc16be82016-09-08 10:35:16 -07001190 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1191#ifndef MS_WINDOWS
1192 && !path->narrow
1193#endif
1194 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001195 PyErr_Format(PyExc_ValueError,
1196 "%s: can't specify dir_fd without matching path",
1197 function_name);
1198 return 1;
1199 }
1200 return 0;
1201}
1202
1203static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001204dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1205{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1207 PyErr_Format(PyExc_ValueError,
1208 "%s: can't specify both dir_fd and fd",
1209 function_name);
1210 return 1;
1211 }
1212 return 0;
1213}
1214
1215static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001216fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1217 int follow_symlinks)
1218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 if ((fd > 0) && (!follow_symlinks)) {
1220 PyErr_Format(PyExc_ValueError,
1221 "%s: cannot use fd and follow_symlinks together",
1222 function_name);
1223 return 1;
1224 }
1225 return 0;
1226}
1227
1228static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001229dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1230 int follow_symlinks)
1231{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001232 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1233 PyErr_Format(PyExc_ValueError,
1234 "%s: cannot use dir_fd and follow_symlinks together",
1235 function_name);
1236 return 1;
1237 }
1238 return 0;
1239}
1240
Larry Hastings2f936352014-08-05 14:04:04 +10001241#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001242 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001243#else
Larry Hastings2f936352014-08-05 14:04:04 +10001244 typedef off_t Py_off_t;
1245#endif
1246
1247static int
1248Py_off_t_converter(PyObject *arg, void *addr)
1249{
1250#ifdef HAVE_LARGEFILE_SUPPORT
1251 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1252#else
1253 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001254#endif
1255 if (PyErr_Occurred())
1256 return 0;
1257 return 1;
1258}
Larry Hastings2f936352014-08-05 14:04:04 +10001259
1260static PyObject *
1261PyLong_FromPy_off_t(Py_off_t offset)
1262{
1263#ifdef HAVE_LARGEFILE_SUPPORT
1264 return PyLong_FromLongLong(offset);
1265#else
1266 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001267#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001268}
1269
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001270#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001271
1272static int
Brian Curtind25aef52011-06-13 15:16:04 -05001273win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274{
Martin Panter70214ad2016-08-04 02:38:59 +00001275 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1276 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001277 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278
1279 if (0 == DeviceIoControl(
1280 reparse_point_handle,
1281 FSCTL_GET_REPARSE_POINT,
1282 NULL, 0, /* in buffer */
1283 target_buffer, sizeof(target_buffer),
1284 &n_bytes_returned,
1285 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001286 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001287
1288 if (reparse_tag)
1289 *reparse_tag = rdb->ReparseTag;
1290
Brian Curtind25aef52011-06-13 15:16:04 -05001291 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001292}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001293
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001294#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001296/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001297#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001298/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001299** environ directly, we must obtain it with _NSGetEnviron(). See also
1300** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001301*/
1302#include <crt_externs.h>
1303static char **environ;
1304#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001306#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307
Barry Warsaw53699e91996-12-10 23:23:01 +00001308static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001309convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310{
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001314#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001315 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001316#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001317
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 d = PyDict_New();
1319 if (d == NULL)
1320 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001321#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 if (environ == NULL)
1323 environ = *_NSGetEnviron();
1324#endif
1325#ifdef MS_WINDOWS
1326 /* _wenviron must be initialized in this way if the program is started
1327 through main() instead of wmain(). */
1328 _wgetenv(L"");
1329 if (_wenviron == NULL)
1330 return d;
1331 /* This part ignores errors */
1332 for (e = _wenviron; *e != NULL; e++) {
1333 PyObject *k;
1334 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001335 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001336 if (p == NULL)
1337 continue;
1338 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1339 if (k == NULL) {
1340 PyErr_Clear();
1341 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001342 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1344 if (v == NULL) {
1345 PyErr_Clear();
1346 Py_DECREF(k);
1347 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001348 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 if (PyDict_GetItem(d, k) == NULL) {
1350 if (PyDict_SetItem(d, k, v) != 0)
1351 PyErr_Clear();
1352 }
1353 Py_DECREF(k);
1354 Py_DECREF(v);
1355 }
1356#else
1357 if (environ == NULL)
1358 return d;
1359 /* This part ignores errors */
1360 for (e = environ; *e != NULL; e++) {
1361 PyObject *k;
1362 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001363 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 if (p == NULL)
1365 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001366 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001367 if (k == NULL) {
1368 PyErr_Clear();
1369 continue;
1370 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001371 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 if (v == NULL) {
1373 PyErr_Clear();
1374 Py_DECREF(k);
1375 continue;
1376 }
1377 if (PyDict_GetItem(d, k) == NULL) {
1378 if (PyDict_SetItem(d, k, v) != 0)
1379 PyErr_Clear();
1380 }
1381 Py_DECREF(k);
1382 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001383 }
1384#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001386}
1387
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388/* Set a POSIX-specific error from errno, and return NULL */
1389
Barry Warsawd58d7641998-07-23 16:14:40 +00001390static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001391posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001392{
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001394}
Mark Hammondef8b6542001-05-13 08:04:26 +00001395
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001396#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001397static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001398win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001399{
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 /* XXX We should pass the function name along in the future.
1401 (winreg.c also wants to pass the function name.)
1402 This would however require an additional param to the
1403 Windows error object, which is non-trivial.
1404 */
1405 errno = GetLastError();
1406 if (filename)
1407 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1408 else
1409 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001410}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001411
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001412static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001413win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001414{
1415 /* XXX - see win32_error for comments on 'function' */
1416 errno = GetLastError();
1417 if (filename)
1418 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001419 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001420 errno,
1421 filename);
1422 else
1423 return PyErr_SetFromWindowsErr(errno);
1424}
1425
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001426#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427
Larry Hastings9cf065c2012-06-22 16:30:09 -07001428static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001429path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001430{
1431#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001432 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1433 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001434#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001435 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436#endif
1437}
1438
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001439static PyObject *
1440path_object_error2(PyObject *path, PyObject *path2)
1441{
1442#ifdef MS_WINDOWS
1443 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1444 PyExc_OSError, 0, path, path2);
1445#else
1446 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1447#endif
1448}
1449
1450static PyObject *
1451path_error(path_t *path)
1452{
1453 return path_object_error(path->object);
1454}
Larry Hastings31826802013-10-19 00:09:25 -07001455
Larry Hastingsb0827312014-02-09 22:05:19 -08001456static PyObject *
1457path_error2(path_t *path, path_t *path2)
1458{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001459 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001460}
1461
1462
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001463/* POSIX generic methods */
1464
Larry Hastings2f936352014-08-05 14:04:04 +10001465static int
1466fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001467{
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001469 int *pointer = (int *)p;
1470 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001471 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001472 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001473 *pointer = fd;
1474 return 1;
1475}
1476
1477static PyObject *
1478posix_fildes_fd(int fd, int (*func)(int))
1479{
1480 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001481 int async_err = 0;
1482
1483 do {
1484 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001485 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001486 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001487 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001488 Py_END_ALLOW_THREADS
1489 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1490 if (res != 0)
1491 return (!async_err) ? posix_error() : NULL;
1492 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001493}
Guido van Rossum21142a01999-01-08 21:05:37 +00001494
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001495
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001496#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001497/* This is a reimplementation of the C library's chdir function,
1498 but one that produces Win32 errors instead of DOS error codes.
1499 chdir is essentially a wrapper around SetCurrentDirectory; however,
1500 it also needs to set "magic" environment variables indicating
1501 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001502static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001503win32_wchdir(LPCWSTR path)
1504{
Victor Stinnered537822015-12-13 21:40:26 +01001505 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001506 int result;
1507 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001508
Victor Stinner8c62be82010-05-06 00:08:46 +00001509 if(!SetCurrentDirectoryW(path))
1510 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001511 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001512 if (!result)
1513 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001514 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001515 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001516 if (!new_path) {
1517 SetLastError(ERROR_OUTOFMEMORY);
1518 return FALSE;
1519 }
1520 result = GetCurrentDirectoryW(result, new_path);
1521 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001522 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 return FALSE;
1524 }
1525 }
1526 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1527 wcsncmp(new_path, L"//", 2) == 0)
1528 /* UNC path, nothing to do. */
1529 return TRUE;
1530 env[1] = new_path[0];
1531 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001532 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001533 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001534 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535}
1536#endif
1537
Martin v. Löwis14694662006-02-03 12:54:16 +00001538#ifdef MS_WINDOWS
1539/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1540 - time stamps are restricted to second resolution
1541 - file modification times suffer from forth-and-back conversions between
1542 UTC and local time
1543 Therefore, we implement our own stat, based on the Win32 API directly.
1544*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001545#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001546#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001547
Victor Stinner6036e442015-03-08 01:58:04 +01001548static void
Steve Dowercc16be82016-09-08 10:35:16 -07001549find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1550 BY_HANDLE_FILE_INFORMATION *info,
1551 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001552{
1553 memset(info, 0, sizeof(*info));
1554 info->dwFileAttributes = pFileData->dwFileAttributes;
1555 info->ftCreationTime = pFileData->ftCreationTime;
1556 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1557 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1558 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1559 info->nFileSizeLow = pFileData->nFileSizeLow;
1560/* info->nNumberOfLinks = 1; */
1561 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1562 *reparse_tag = pFileData->dwReserved0;
1563 else
1564 *reparse_tag = 0;
1565}
1566
Guido van Rossumd8faa362007-04-27 19:54:29 +00001567static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001568attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001569{
Victor Stinner8c62be82010-05-06 00:08:46 +00001570 HANDLE hFindFile;
1571 WIN32_FIND_DATAW FileData;
1572 hFindFile = FindFirstFileW(pszFile, &FileData);
1573 if (hFindFile == INVALID_HANDLE_VALUE)
1574 return FALSE;
1575 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001576 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001578}
1579
Brian Curtind25aef52011-06-13 15:16:04 -05001580static BOOL
1581get_target_path(HANDLE hdl, wchar_t **target_path)
1582{
1583 int buf_size, result_length;
1584 wchar_t *buf;
1585
1586 /* We have a good handle to the target, use it to determine
1587 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001588 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1589 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001590 if(!buf_size)
1591 return FALSE;
1592
Victor Stinnerc36674a2016-03-16 14:30:16 +01001593 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001594 if (!buf) {
1595 SetLastError(ERROR_OUTOFMEMORY);
1596 return FALSE;
1597 }
1598
Steve Dower2ea51c92015-03-20 21:49:12 -07001599 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001600 buf, buf_size, VOLUME_NAME_DOS);
1601
1602 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001603 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001604 return FALSE;
1605 }
1606
1607 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001608 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001609 return FALSE;
1610 }
1611
1612 buf[result_length] = 0;
1613
1614 *target_path = buf;
1615 return TRUE;
1616}
1617
1618static int
Steve Dowercc16be82016-09-08 10:35:16 -07001619win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001620 BOOL traverse)
1621{
Victor Stinner26de69d2011-06-17 15:15:38 +02001622 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001623 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001625 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001626 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001627 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001628
Steve Dowercc16be82016-09-08 10:35:16 -07001629 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001630 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001631 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 0, /* share mode */
1633 NULL, /* security attributes */
1634 OPEN_EXISTING,
1635 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001636 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1637 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001638 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001639 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1640 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001641 NULL);
1642
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001644 /* Either the target doesn't exist, or we don't have access to
1645 get a handle to it. If the former, we need to return an error.
1646 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001647 DWORD lastError = GetLastError();
1648 if (lastError != ERROR_ACCESS_DENIED &&
1649 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001650 return -1;
1651 /* Could not get attributes on open file. Fall back to
1652 reading the directory. */
1653 if (!attributes_from_dir(path, &info, &reparse_tag))
1654 /* Very strange. This should not fail now */
1655 return -1;
1656 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1657 if (traverse) {
1658 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001659 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001660 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001661 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001663 } else {
1664 if (!GetFileInformationByHandle(hFile, &info)) {
1665 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001666 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001667 }
1668 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001669 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1670 return -1;
1671
1672 /* Close the outer open file handle now that we're about to
1673 reopen it with different flags. */
1674 if (!CloseHandle(hFile))
1675 return -1;
1676
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001677 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001678 /* In order to call GetFinalPathNameByHandle we need to open
1679 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001680 hFile2 = CreateFileW(
1681 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1682 NULL, OPEN_EXISTING,
1683 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1684 NULL);
1685 if (hFile2 == INVALID_HANDLE_VALUE)
1686 return -1;
1687
1688 if (!get_target_path(hFile2, &target_path))
1689 return -1;
1690
Steve Dowercc16be82016-09-08 10:35:16 -07001691 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001692 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001693 return code;
1694 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001695 } else
1696 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001698 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001699
1700 /* Set S_IEXEC if it is an .exe, .bat, ... */
1701 dot = wcsrchr(path, '.');
1702 if (dot) {
1703 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1704 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1705 result->st_mode |= 0111;
1706 }
1707 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001708}
1709
1710static int
Steve Dowercc16be82016-09-08 10:35:16 -07001711win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001712{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001713 /* Protocol violation: we explicitly clear errno, instead of
1714 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001715 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001716 errno = 0;
1717 return code;
1718}
Brian Curtind25aef52011-06-13 15:16:04 -05001719/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001720
1721 In Posix, stat automatically traverses symlinks and returns the stat
1722 structure for the target. In Windows, the equivalent GetFileAttributes by
1723 default does not traverse symlinks and instead returns attributes for
1724 the symlink.
1725
1726 Therefore, win32_lstat will get the attributes traditionally, and
1727 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001728 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001729
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001730static int
Steve Dowercc16be82016-09-08 10:35:16 -07001731win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001732{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001733 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001734}
1735
Victor Stinner8c62be82010-05-06 00:08:46 +00001736static int
Steve Dowercc16be82016-09-08 10:35:16 -07001737win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001738{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001739 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001740}
1741
Martin v. Löwis14694662006-02-03 12:54:16 +00001742#endif /* MS_WINDOWS */
1743
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001744PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001745"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001746This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001747 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001748or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1749\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001750Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1751or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001752\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001753See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754
1755static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001756 {"st_mode", "protection bits"},
1757 {"st_ino", "inode"},
1758 {"st_dev", "device"},
1759 {"st_nlink", "number of hard links"},
1760 {"st_uid", "user ID of owner"},
1761 {"st_gid", "group ID of owner"},
1762 {"st_size", "total size, in bytes"},
1763 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1764 {NULL, "integer time of last access"},
1765 {NULL, "integer time of last modification"},
1766 {NULL, "integer time of last change"},
1767 {"st_atime", "time of last access"},
1768 {"st_mtime", "time of last modification"},
1769 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001770 {"st_atime_ns", "time of last access in nanoseconds"},
1771 {"st_mtime_ns", "time of last modification in nanoseconds"},
1772 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001773#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001774 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001775#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001776#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001777 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001778#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001779#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001781#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001782#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001783 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001784#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001785#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001786 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001787#endif
1788#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001790#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001791#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1792 {"st_file_attributes", "Windows file attribute bits"},
1793#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001795};
1796
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001797#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001798#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001799#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001800#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001801#endif
1802
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001803#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001804#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1805#else
1806#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1807#endif
1808
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001809#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001810#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1811#else
1812#define ST_RDEV_IDX ST_BLOCKS_IDX
1813#endif
1814
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001815#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1816#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1817#else
1818#define ST_FLAGS_IDX ST_RDEV_IDX
1819#endif
1820
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001821#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001822#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001823#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001824#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001825#endif
1826
1827#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1828#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1829#else
1830#define ST_BIRTHTIME_IDX ST_GEN_IDX
1831#endif
1832
Zachary Ware63f277b2014-06-19 09:46:37 -05001833#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1834#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1835#else
1836#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1837#endif
1838
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001839static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 "stat_result", /* name */
1841 stat_result__doc__, /* doc */
1842 stat_result_fields,
1843 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001844};
1845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001847"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1848This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001849 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001850or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001852See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853
1854static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 {"f_bsize", },
1856 {"f_frsize", },
1857 {"f_blocks", },
1858 {"f_bfree", },
1859 {"f_bavail", },
1860 {"f_files", },
1861 {"f_ffree", },
1862 {"f_favail", },
1863 {"f_flag", },
1864 {"f_namemax",},
1865 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001866};
1867
1868static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 "statvfs_result", /* name */
1870 statvfs_result__doc__, /* doc */
1871 statvfs_result_fields,
1872 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001873};
1874
Ross Lagerwall7807c352011-03-17 20:20:30 +02001875#if defined(HAVE_WAITID) && !defined(__APPLE__)
1876PyDoc_STRVAR(waitid_result__doc__,
1877"waitid_result: Result from waitid.\n\n\
1878This object may be accessed either as a tuple of\n\
1879 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1880or via the attributes si_pid, si_uid, and so on.\n\
1881\n\
1882See os.waitid for more information.");
1883
1884static PyStructSequence_Field waitid_result_fields[] = {
1885 {"si_pid", },
1886 {"si_uid", },
1887 {"si_signo", },
1888 {"si_status", },
1889 {"si_code", },
1890 {0}
1891};
1892
1893static PyStructSequence_Desc waitid_result_desc = {
1894 "waitid_result", /* name */
1895 waitid_result__doc__, /* doc */
1896 waitid_result_fields,
1897 5
1898};
1899static PyTypeObject WaitidResultType;
1900#endif
1901
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001902static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001903static PyTypeObject StatResultType;
1904static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001905#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001906static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001907#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001908static newfunc structseq_new;
1909
1910static PyObject *
1911statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1912{
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 PyStructSequence *result;
1914 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001915
Victor Stinner8c62be82010-05-06 00:08:46 +00001916 result = (PyStructSequence*)structseq_new(type, args, kwds);
1917 if (!result)
1918 return NULL;
1919 /* If we have been initialized from a tuple,
1920 st_?time might be set to None. Initialize it
1921 from the int slots. */
1922 for (i = 7; i <= 9; i++) {
1923 if (result->ob_item[i+3] == Py_None) {
1924 Py_DECREF(Py_None);
1925 Py_INCREF(result->ob_item[i]);
1926 result->ob_item[i+3] = result->ob_item[i];
1927 }
1928 }
1929 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001930}
1931
1932
1933
1934/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001935static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001936
1937PyDoc_STRVAR(stat_float_times__doc__,
1938"stat_float_times([newval]) -> oldval\n\n\
1939Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001940\n\
1941If value is True, future calls to stat() return floats; if it is False,\n\
1942future calls return ints.\n\
1943If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001944
Larry Hastings2f936352014-08-05 14:04:04 +10001945/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001946static PyObject*
1947stat_float_times(PyObject* self, PyObject *args)
1948{
Victor Stinner8c62be82010-05-06 00:08:46 +00001949 int newval = -1;
1950 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1951 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001952 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1953 "stat_float_times() is deprecated",
1954 1))
1955 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 if (newval == -1)
1957 /* Return old value */
1958 return PyBool_FromLong(_stat_float_times);
1959 _stat_float_times = newval;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001960 Py_RETURN_NONE;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001961}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001962
Larry Hastings6fe20b32012-04-19 15:07:49 -07001963static PyObject *billion = NULL;
1964
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001965static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001966fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001967{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001968 PyObject *s = _PyLong_FromTime_t(sec);
1969 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1970 PyObject *s_in_ns = NULL;
1971 PyObject *ns_total = NULL;
1972 PyObject *float_s = NULL;
1973
1974 if (!(s && ns_fractional))
1975 goto exit;
1976
1977 s_in_ns = PyNumber_Multiply(s, billion);
1978 if (!s_in_ns)
1979 goto exit;
1980
1981 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1982 if (!ns_total)
1983 goto exit;
1984
Victor Stinner4195b5c2012-02-08 23:03:19 +01001985 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001986 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1987 if (!float_s)
1988 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001990 else {
1991 float_s = s;
1992 Py_INCREF(float_s);
1993 }
1994
1995 PyStructSequence_SET_ITEM(v, index, s);
1996 PyStructSequence_SET_ITEM(v, index+3, float_s);
1997 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1998 s = NULL;
1999 float_s = NULL;
2000 ns_total = NULL;
2001exit:
2002 Py_XDECREF(s);
2003 Py_XDECREF(ns_fractional);
2004 Py_XDECREF(s_in_ns);
2005 Py_XDECREF(ns_total);
2006 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002007}
2008
Tim Peters5aa91602002-01-30 05:46:57 +00002009/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002010 (used by posix_stat() and posix_fstat()) */
2011static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002012_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002013{
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 unsigned long ansec, mnsec, cnsec;
2015 PyObject *v = PyStructSequence_New(&StatResultType);
2016 if (v == NULL)
2017 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002018
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002020 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002021 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002022#ifdef MS_WINDOWS
2023 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002024#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002025 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002026#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002027 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002028#if defined(MS_WINDOWS)
2029 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2030 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2031#else
2032 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2033 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2034#endif
xdegaye50e86032017-05-22 11:15:08 +02002035 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2036 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002037
Martin v. Löwis14694662006-02-03 12:54:16 +00002038#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002039 ansec = st->st_atim.tv_nsec;
2040 mnsec = st->st_mtim.tv_nsec;
2041 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002042#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002043 ansec = st->st_atimespec.tv_nsec;
2044 mnsec = st->st_mtimespec.tv_nsec;
2045 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002046#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 ansec = st->st_atime_nsec;
2048 mnsec = st->st_mtime_nsec;
2049 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002050#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002052#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002053 fill_time(v, 7, st->st_atime, ansec);
2054 fill_time(v, 8, st->st_mtime, mnsec);
2055 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002056
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002057#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2059 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002060#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002061#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2063 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002064#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002065#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002066 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2067 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002068#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002069#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002070 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2071 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002072#endif
2073#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002074 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002075 PyObject *val;
2076 unsigned long bsec,bnsec;
2077 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002078#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002079 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002080#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002081 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002082#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002083 if (_stat_float_times) {
2084 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2085 } else {
2086 val = PyLong_FromLong((long)bsec);
2087 }
2088 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2089 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002091#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002092#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002093 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2094 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002095#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002096#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2097 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2098 PyLong_FromUnsignedLong(st->st_file_attributes));
2099#endif
Fred Drake699f3522000-06-29 21:12:41 +00002100
Victor Stinner8c62be82010-05-06 00:08:46 +00002101 if (PyErr_Occurred()) {
2102 Py_DECREF(v);
2103 return NULL;
2104 }
Fred Drake699f3522000-06-29 21:12:41 +00002105
Victor Stinner8c62be82010-05-06 00:08:46 +00002106 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002107}
2108
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002109/* POSIX methods */
2110
Guido van Rossum94f6f721999-01-06 18:42:14 +00002111
2112static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002113posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002114 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002115{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002116 STRUCT_STAT st;
2117 int result;
2118
2119#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2120 if (follow_symlinks_specified(function_name, follow_symlinks))
2121 return NULL;
2122#endif
2123
2124 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2125 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2126 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2127 return NULL;
2128
2129 Py_BEGIN_ALLOW_THREADS
2130 if (path->fd != -1)
2131 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002132#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002133 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002134 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002135 else
Steve Dowercc16be82016-09-08 10:35:16 -07002136 result = win32_lstat(path->wide, &st);
2137#else
2138 else
2139#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002140 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2141 result = LSTAT(path->narrow, &st);
2142 else
Steve Dowercc16be82016-09-08 10:35:16 -07002143#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002144#ifdef HAVE_FSTATAT
2145 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2146 result = fstatat(dir_fd, path->narrow, &st,
2147 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2148 else
Steve Dowercc16be82016-09-08 10:35:16 -07002149#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002150 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002151#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002152 Py_END_ALLOW_THREADS
2153
Victor Stinner292c8352012-10-30 02:17:38 +01002154 if (result != 0) {
2155 return path_error(path);
2156 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002157
2158 return _pystat_fromstructstat(&st);
2159}
2160
Larry Hastings2f936352014-08-05 14:04:04 +10002161/*[python input]
2162
2163for s in """
2164
2165FACCESSAT
2166FCHMODAT
2167FCHOWNAT
2168FSTATAT
2169LINKAT
2170MKDIRAT
2171MKFIFOAT
2172MKNODAT
2173OPENAT
2174READLINKAT
2175SYMLINKAT
2176UNLINKAT
2177
2178""".strip().split():
2179 s = s.strip()
2180 print("""
2181#ifdef HAVE_{s}
2182 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002183#else
Larry Hastings2f936352014-08-05 14:04:04 +10002184 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002185#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002186""".rstrip().format(s=s))
2187
2188for s in """
2189
2190FCHDIR
2191FCHMOD
2192FCHOWN
2193FDOPENDIR
2194FEXECVE
2195FPATHCONF
2196FSTATVFS
2197FTRUNCATE
2198
2199""".strip().split():
2200 s = s.strip()
2201 print("""
2202#ifdef HAVE_{s}
2203 #define PATH_HAVE_{s} 1
2204#else
2205 #define PATH_HAVE_{s} 0
2206#endif
2207
2208""".rstrip().format(s=s))
2209[python start generated code]*/
2210
2211#ifdef HAVE_FACCESSAT
2212 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2213#else
2214 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2215#endif
2216
2217#ifdef HAVE_FCHMODAT
2218 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2219#else
2220 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2221#endif
2222
2223#ifdef HAVE_FCHOWNAT
2224 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2225#else
2226 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2227#endif
2228
2229#ifdef HAVE_FSTATAT
2230 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2231#else
2232 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2233#endif
2234
2235#ifdef HAVE_LINKAT
2236 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2237#else
2238 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2239#endif
2240
2241#ifdef HAVE_MKDIRAT
2242 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2243#else
2244 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2245#endif
2246
2247#ifdef HAVE_MKFIFOAT
2248 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2249#else
2250 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2251#endif
2252
2253#ifdef HAVE_MKNODAT
2254 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2255#else
2256 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2257#endif
2258
2259#ifdef HAVE_OPENAT
2260 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2261#else
2262 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2263#endif
2264
2265#ifdef HAVE_READLINKAT
2266 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2267#else
2268 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2269#endif
2270
2271#ifdef HAVE_SYMLINKAT
2272 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2273#else
2274 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2275#endif
2276
2277#ifdef HAVE_UNLINKAT
2278 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2279#else
2280 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2281#endif
2282
2283#ifdef HAVE_FCHDIR
2284 #define PATH_HAVE_FCHDIR 1
2285#else
2286 #define PATH_HAVE_FCHDIR 0
2287#endif
2288
2289#ifdef HAVE_FCHMOD
2290 #define PATH_HAVE_FCHMOD 1
2291#else
2292 #define PATH_HAVE_FCHMOD 0
2293#endif
2294
2295#ifdef HAVE_FCHOWN
2296 #define PATH_HAVE_FCHOWN 1
2297#else
2298 #define PATH_HAVE_FCHOWN 0
2299#endif
2300
2301#ifdef HAVE_FDOPENDIR
2302 #define PATH_HAVE_FDOPENDIR 1
2303#else
2304 #define PATH_HAVE_FDOPENDIR 0
2305#endif
2306
2307#ifdef HAVE_FEXECVE
2308 #define PATH_HAVE_FEXECVE 1
2309#else
2310 #define PATH_HAVE_FEXECVE 0
2311#endif
2312
2313#ifdef HAVE_FPATHCONF
2314 #define PATH_HAVE_FPATHCONF 1
2315#else
2316 #define PATH_HAVE_FPATHCONF 0
2317#endif
2318
2319#ifdef HAVE_FSTATVFS
2320 #define PATH_HAVE_FSTATVFS 1
2321#else
2322 #define PATH_HAVE_FSTATVFS 0
2323#endif
2324
2325#ifdef HAVE_FTRUNCATE
2326 #define PATH_HAVE_FTRUNCATE 1
2327#else
2328 #define PATH_HAVE_FTRUNCATE 0
2329#endif
2330/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002331
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002332#ifdef MS_WINDOWS
2333 #undef PATH_HAVE_FTRUNCATE
2334 #define PATH_HAVE_FTRUNCATE 1
2335#endif
Larry Hastings31826802013-10-19 00:09:25 -07002336
Larry Hastings61272b72014-01-07 12:41:53 -08002337/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002338
2339class path_t_converter(CConverter):
2340
2341 type = "path_t"
2342 impl_by_reference = True
2343 parse_by_reference = True
2344
2345 converter = 'path_converter'
2346
2347 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002348 # right now path_t doesn't support default values.
2349 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002350 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002351 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002352
Larry Hastings2f936352014-08-05 14:04:04 +10002353 if self.c_default not in (None, 'Py_None'):
2354 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002355
2356 self.nullable = nullable
2357 self.allow_fd = allow_fd
2358
Larry Hastings7726ac92014-01-31 22:03:12 -08002359 def pre_render(self):
2360 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002361 if isinstance(value, str):
2362 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002363 return str(int(bool(value)))
2364
2365 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002366 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002367 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002368 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002369 strify(self.nullable),
2370 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002371 )
2372
2373 def cleanup(self):
2374 return "path_cleanup(&" + self.name + ");\n"
2375
2376
2377class dir_fd_converter(CConverter):
2378 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002379
Larry Hastings2f936352014-08-05 14:04:04 +10002380 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002381 if self.default in (unspecified, None):
2382 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002383 if isinstance(requires, str):
2384 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2385 else:
2386 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002387
Larry Hastings2f936352014-08-05 14:04:04 +10002388class fildes_converter(CConverter):
2389 type = 'int'
2390 converter = 'fildes_converter'
2391
2392class uid_t_converter(CConverter):
2393 type = "uid_t"
2394 converter = '_Py_Uid_Converter'
2395
2396class gid_t_converter(CConverter):
2397 type = "gid_t"
2398 converter = '_Py_Gid_Converter'
2399
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002400class dev_t_converter(CConverter):
2401 type = 'dev_t'
2402 converter = '_Py_Dev_Converter'
2403
2404class dev_t_return_converter(unsigned_long_return_converter):
2405 type = 'dev_t'
2406 conversion_fn = '_PyLong_FromDev'
2407 unsigned_cast = '(dev_t)'
2408
Larry Hastings2f936352014-08-05 14:04:04 +10002409class FSConverter_converter(CConverter):
2410 type = 'PyObject *'
2411 converter = 'PyUnicode_FSConverter'
2412 def converter_init(self):
2413 if self.default is not unspecified:
2414 fail("FSConverter_converter does not support default values")
2415 self.c_default = 'NULL'
2416
2417 def cleanup(self):
2418 return "Py_XDECREF(" + self.name + ");\n"
2419
2420class pid_t_converter(CConverter):
2421 type = 'pid_t'
2422 format_unit = '" _Py_PARSE_PID "'
2423
2424class idtype_t_converter(int_converter):
2425 type = 'idtype_t'
2426
2427class id_t_converter(CConverter):
2428 type = 'id_t'
2429 format_unit = '" _Py_PARSE_PID "'
2430
Benjamin Petersonca470632016-09-06 13:47:26 -07002431class intptr_t_converter(CConverter):
2432 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002433 format_unit = '" _Py_PARSE_INTPTR "'
2434
2435class Py_off_t_converter(CConverter):
2436 type = 'Py_off_t'
2437 converter = 'Py_off_t_converter'
2438
2439class Py_off_t_return_converter(long_return_converter):
2440 type = 'Py_off_t'
2441 conversion_fn = 'PyLong_FromPy_off_t'
2442
2443class path_confname_converter(CConverter):
2444 type="int"
2445 converter="conv_path_confname"
2446
2447class confstr_confname_converter(path_confname_converter):
2448 converter='conv_confstr_confname'
2449
2450class sysconf_confname_converter(path_confname_converter):
2451 converter="conv_sysconf_confname"
2452
2453class sched_param_converter(CConverter):
2454 type = 'struct sched_param'
2455 converter = 'convert_sched_param'
2456 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002457
Larry Hastings61272b72014-01-07 12:41:53 -08002458[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002459/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002460
Larry Hastings61272b72014-01-07 12:41:53 -08002461/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002462
Larry Hastings2a727912014-01-16 11:32:01 -08002463os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002464
2465 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002466 Path to be examined; can be string, bytes, path-like object or
2467 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002468
2469 *
2470
Larry Hastings2f936352014-08-05 14:04:04 +10002471 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002472 If not None, it should be a file descriptor open to a directory,
2473 and path should be a relative string; path will then be relative to
2474 that directory.
2475
2476 follow_symlinks: bool = True
2477 If False, and the last element of the path is a symbolic link,
2478 stat will examine the symbolic link itself instead of the file
2479 the link points to.
2480
2481Perform a stat system call on the given path.
2482
2483dir_fd and follow_symlinks may not be implemented
2484 on your platform. If they are unavailable, using them will raise a
2485 NotImplementedError.
2486
2487It's an error to use dir_fd or follow_symlinks when specifying path as
2488 an open file descriptor.
2489
Larry Hastings61272b72014-01-07 12:41:53 -08002490[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002491
Larry Hastings31826802013-10-19 00:09:25 -07002492static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002493os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002494/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002495{
2496 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2497}
2498
Larry Hastings2f936352014-08-05 14:04:04 +10002499
2500/*[clinic input]
2501os.lstat
2502
2503 path : path_t
2504
2505 *
2506
2507 dir_fd : dir_fd(requires='fstatat') = None
2508
2509Perform a stat system call on the given path, without following symbolic links.
2510
2511Like stat(), but do not follow symbolic links.
2512Equivalent to stat(path, follow_symlinks=False).
2513[clinic start generated code]*/
2514
Larry Hastings2f936352014-08-05 14:04:04 +10002515static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002516os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2517/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002518{
2519 int follow_symlinks = 0;
2520 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2521}
Larry Hastings31826802013-10-19 00:09:25 -07002522
Larry Hastings2f936352014-08-05 14:04:04 +10002523
Larry Hastings61272b72014-01-07 12:41:53 -08002524/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002525os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002526
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002527 path: path_t
2528 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002529
2530 mode: int
2531 Operating-system mode bitfield. Can be F_OK to test existence,
2532 or the inclusive-OR of R_OK, W_OK, and X_OK.
2533
2534 *
2535
Larry Hastings2f936352014-08-05 14:04:04 +10002536 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002537 If not None, it should be a file descriptor open to a directory,
2538 and path should be relative; path will then be relative to that
2539 directory.
2540
2541 effective_ids: bool = False
2542 If True, access will use the effective uid/gid instead of
2543 the real uid/gid.
2544
2545 follow_symlinks: bool = True
2546 If False, and the last element of the path is a symbolic link,
2547 access will examine the symbolic link itself instead of the file
2548 the link points to.
2549
2550Use the real uid/gid to test for access to a path.
2551
2552{parameters}
2553dir_fd, effective_ids, and follow_symlinks may not be implemented
2554 on your platform. If they are unavailable, using them will raise a
2555 NotImplementedError.
2556
2557Note that most operations will use the effective uid/gid, therefore this
2558 routine can be used in a suid/sgid environment to test if the invoking user
2559 has the specified access to the path.
2560
Larry Hastings61272b72014-01-07 12:41:53 -08002561[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002562
Larry Hastings2f936352014-08-05 14:04:04 +10002563static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002564os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002565 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002566/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002567{
Larry Hastings2f936352014-08-05 14:04:04 +10002568 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002569
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002570#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002572#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002573 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002574#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576#ifndef HAVE_FACCESSAT
2577 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002578 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002579
2580 if (effective_ids) {
2581 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002582 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583 }
2584#endif
2585
2586#ifdef MS_WINDOWS
2587 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002588 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589 Py_END_ALLOW_THREADS
2590
2591 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002592 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593 * * we didn't get a -1, and
2594 * * write access wasn't requested,
2595 * * or the file isn't read-only,
2596 * * or it's a directory.
2597 * (Directories cannot be read-only on Windows.)
2598 */
Larry Hastings2f936352014-08-05 14:04:04 +10002599 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002600 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002602 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603#else
2604
2605 Py_BEGIN_ALLOW_THREADS
2606#ifdef HAVE_FACCESSAT
2607 if ((dir_fd != DEFAULT_DIR_FD) ||
2608 effective_ids ||
2609 !follow_symlinks) {
2610 int flags = 0;
2611 if (!follow_symlinks)
2612 flags |= AT_SYMLINK_NOFOLLOW;
2613 if (effective_ids)
2614 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002615 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002616 }
2617 else
2618#endif
Larry Hastings31826802013-10-19 00:09:25 -07002619 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002620 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002621 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622#endif
2623
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002625}
2626
Guido van Rossumd371ff11999-01-25 16:12:23 +00002627#ifndef F_OK
2628#define F_OK 0
2629#endif
2630#ifndef R_OK
2631#define R_OK 4
2632#endif
2633#ifndef W_OK
2634#define W_OK 2
2635#endif
2636#ifndef X_OK
2637#define X_OK 1
2638#endif
2639
Larry Hastings31826802013-10-19 00:09:25 -07002640
Guido van Rossumd371ff11999-01-25 16:12:23 +00002641#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002642/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002643os.ttyname -> DecodeFSDefault
2644
2645 fd: int
2646 Integer file descriptor handle.
2647
2648 /
2649
2650Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002651[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002652
Larry Hastings31826802013-10-19 00:09:25 -07002653static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002654os_ttyname_impl(PyObject *module, int fd)
2655/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002656{
2657 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002658
Larry Hastings31826802013-10-19 00:09:25 -07002659 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002661 posix_error();
2662 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002663}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002664#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002666#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002667/*[clinic input]
2668os.ctermid
2669
2670Return the name of the controlling terminal for this process.
2671[clinic start generated code]*/
2672
Larry Hastings2f936352014-08-05 14:04:04 +10002673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002674os_ctermid_impl(PyObject *module)
2675/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002676{
Victor Stinner8c62be82010-05-06 00:08:46 +00002677 char *ret;
2678 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002679
Greg Wardb48bc172000-03-01 21:51:56 +00002680#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002682#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 if (ret == NULL)
2686 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002687 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002688}
Larry Hastings2f936352014-08-05 14:04:04 +10002689#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002690
Larry Hastings2f936352014-08-05 14:04:04 +10002691
2692/*[clinic input]
2693os.chdir
2694
2695 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2696
2697Change the current working directory to the specified path.
2698
2699path may always be specified as a string.
2700On some platforms, path may also be specified as an open file descriptor.
2701 If this functionality is unavailable, using it raises an exception.
2702[clinic start generated code]*/
2703
Larry Hastings2f936352014-08-05 14:04:04 +10002704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002705os_chdir_impl(PyObject *module, path_t *path)
2706/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002707{
2708 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709
2710 Py_BEGIN_ALLOW_THREADS
2711#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002712 /* on unix, success = 0, on windows, success = !0 */
2713 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002714#else
2715#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002716 if (path->fd != -1)
2717 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002718 else
2719#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002720 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721#endif
2722 Py_END_ALLOW_THREADS
2723
2724 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002725 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726 }
2727
Larry Hastings2f936352014-08-05 14:04:04 +10002728 Py_RETURN_NONE;
2729}
2730
2731
2732#ifdef HAVE_FCHDIR
2733/*[clinic input]
2734os.fchdir
2735
2736 fd: fildes
2737
2738Change to the directory of the given file descriptor.
2739
2740fd must be opened on a directory, not a file.
2741Equivalent to os.chdir(fd).
2742
2743[clinic start generated code]*/
2744
Fred Drake4d1e64b2002-04-15 19:40:07 +00002745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002746os_fchdir_impl(PyObject *module, int fd)
2747/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002748{
Larry Hastings2f936352014-08-05 14:04:04 +10002749 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002750}
2751#endif /* HAVE_FCHDIR */
2752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002753
Larry Hastings2f936352014-08-05 14:04:04 +10002754/*[clinic input]
2755os.chmod
2756
2757 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2758 Path to be modified. May always be specified as a str or bytes.
2759 On some platforms, path may also be specified as an open file descriptor.
2760 If this functionality is unavailable, using it raises an exception.
2761
2762 mode: int
2763 Operating-system mode bitfield.
2764
2765 *
2766
2767 dir_fd : dir_fd(requires='fchmodat') = None
2768 If not None, it should be a file descriptor open to a directory,
2769 and path should be relative; path will then be relative to that
2770 directory.
2771
2772 follow_symlinks: bool = True
2773 If False, and the last element of the path is a symbolic link,
2774 chmod will modify the symbolic link itself instead of the file
2775 the link points to.
2776
2777Change the access permissions of a file.
2778
2779It is an error to use dir_fd or follow_symlinks when specifying path as
2780 an open file descriptor.
2781dir_fd and follow_symlinks may not be implemented on your platform.
2782 If they are unavailable, using them will raise a NotImplementedError.
2783
2784[clinic start generated code]*/
2785
Larry Hastings2f936352014-08-05 14:04:04 +10002786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002787os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002788 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002789/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002790{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002791 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002793#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002794 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002796
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797#ifdef HAVE_FCHMODAT
2798 int fchmodat_nofollow_unsupported = 0;
2799#endif
2800
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2802 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002803 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804#endif
2805
2806#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002807 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002808 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002809 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810 result = 0;
2811 else {
2812 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002813 attr &= ~FILE_ATTRIBUTE_READONLY;
2814 else
2815 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002816 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 }
2818 Py_END_ALLOW_THREADS
2819
2820 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002821 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822 }
2823#else /* MS_WINDOWS */
2824 Py_BEGIN_ALLOW_THREADS
2825#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002826 if (path->fd != -1)
2827 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828 else
2829#endif
2830#ifdef HAVE_LCHMOD
2831 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002832 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002833 else
2834#endif
2835#ifdef HAVE_FCHMODAT
2836 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2837 /*
2838 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2839 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002840 * and then says it isn't implemented yet.
2841 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842 *
2843 * Once it is supported, os.chmod will automatically
2844 * support dir_fd and follow_symlinks=False. (Hopefully.)
2845 * Until then, we need to be careful what exception we raise.
2846 */
Larry Hastings2f936352014-08-05 14:04:04 +10002847 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002848 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2849 /*
2850 * But wait! We can't throw the exception without allowing threads,
2851 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2852 */
2853 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002854 result &&
2855 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2856 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 }
2858 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002859#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002860 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861 Py_END_ALLOW_THREADS
2862
2863 if (result) {
2864#ifdef HAVE_FCHMODAT
2865 if (fchmodat_nofollow_unsupported) {
2866 if (dir_fd != DEFAULT_DIR_FD)
2867 dir_fd_and_follow_symlinks_invalid("chmod",
2868 dir_fd, follow_symlinks);
2869 else
2870 follow_symlinks_specified("chmod", follow_symlinks);
2871 }
2872 else
2873#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002874 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002875 }
2876#endif
2877
Larry Hastings2f936352014-08-05 14:04:04 +10002878 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002879}
2880
Larry Hastings9cf065c2012-06-22 16:30:09 -07002881
Christian Heimes4e30a842007-11-30 22:12:06 +00002882#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002883/*[clinic input]
2884os.fchmod
2885
2886 fd: int
2887 mode: int
2888
2889Change the access permissions of the file given by file descriptor fd.
2890
2891Equivalent to os.chmod(fd, mode).
2892[clinic start generated code]*/
2893
Larry Hastings2f936352014-08-05 14:04:04 +10002894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002895os_fchmod_impl(PyObject *module, int fd, int mode)
2896/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002897{
2898 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002899 int async_err = 0;
2900
2901 do {
2902 Py_BEGIN_ALLOW_THREADS
2903 res = fchmod(fd, mode);
2904 Py_END_ALLOW_THREADS
2905 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2906 if (res != 0)
2907 return (!async_err) ? posix_error() : NULL;
2908
Victor Stinner8c62be82010-05-06 00:08:46 +00002909 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002910}
2911#endif /* HAVE_FCHMOD */
2912
Larry Hastings2f936352014-08-05 14:04:04 +10002913
Christian Heimes4e30a842007-11-30 22:12:06 +00002914#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002915/*[clinic input]
2916os.lchmod
2917
2918 path: path_t
2919 mode: int
2920
2921Change the access permissions of a file, without following symbolic links.
2922
2923If path is a symlink, this affects the link itself rather than the target.
2924Equivalent to chmod(path, mode, follow_symlinks=False)."
2925[clinic start generated code]*/
2926
Larry Hastings2f936352014-08-05 14:04:04 +10002927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002928os_lchmod_impl(PyObject *module, path_t *path, int mode)
2929/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002930{
Victor Stinner8c62be82010-05-06 00:08:46 +00002931 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002932 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002933 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002935 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002936 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002937 return NULL;
2938 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002940}
2941#endif /* HAVE_LCHMOD */
2942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002943
Thomas Wouterscf297e42007-02-23 15:07:44 +00002944#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002945/*[clinic input]
2946os.chflags
2947
2948 path: path_t
2949 flags: unsigned_long(bitwise=True)
2950 follow_symlinks: bool=True
2951
2952Set file flags.
2953
2954If follow_symlinks is False, and the last element of the path is a symbolic
2955 link, chflags will change flags on the symbolic link itself instead of the
2956 file the link points to.
2957follow_symlinks may not be implemented on your platform. If it is
2958unavailable, using it will raise a NotImplementedError.
2959
2960[clinic start generated code]*/
2961
Larry Hastings2f936352014-08-05 14:04:04 +10002962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002963os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002964 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002965/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002966{
2967 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002968
2969#ifndef HAVE_LCHFLAGS
2970 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002971 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972#endif
2973
Victor Stinner8c62be82010-05-06 00:08:46 +00002974 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975#ifdef HAVE_LCHFLAGS
2976 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002977 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002978 else
2979#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002980 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002981 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002982
Larry Hastings2f936352014-08-05 14:04:04 +10002983 if (result)
2984 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002985
Larry Hastings2f936352014-08-05 14:04:04 +10002986 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002987}
2988#endif /* HAVE_CHFLAGS */
2989
Larry Hastings2f936352014-08-05 14:04:04 +10002990
Thomas Wouterscf297e42007-02-23 15:07:44 +00002991#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002992/*[clinic input]
2993os.lchflags
2994
2995 path: path_t
2996 flags: unsigned_long(bitwise=True)
2997
2998Set file flags.
2999
3000This function will not follow symbolic links.
3001Equivalent to chflags(path, flags, follow_symlinks=False).
3002[clinic start generated code]*/
3003
Larry Hastings2f936352014-08-05 14:04:04 +10003004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003005os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3006/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003007{
Victor Stinner8c62be82010-05-06 00:08:46 +00003008 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003009 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003010 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003012 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003013 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003014 }
Victor Stinner292c8352012-10-30 02:17:38 +01003015 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003016}
3017#endif /* HAVE_LCHFLAGS */
3018
Larry Hastings2f936352014-08-05 14:04:04 +10003019
Martin v. Löwis244edc82001-10-04 22:44:26 +00003020#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003021/*[clinic input]
3022os.chroot
3023 path: path_t
3024
3025Change root directory to path.
3026
3027[clinic start generated code]*/
3028
Larry Hastings2f936352014-08-05 14:04:04 +10003029static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003030os_chroot_impl(PyObject *module, path_t *path)
3031/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003032{
3033 int res;
3034 Py_BEGIN_ALLOW_THREADS
3035 res = chroot(path->narrow);
3036 Py_END_ALLOW_THREADS
3037 if (res < 0)
3038 return path_error(path);
3039 Py_RETURN_NONE;
3040}
3041#endif /* HAVE_CHROOT */
3042
Martin v. Löwis244edc82001-10-04 22:44:26 +00003043
Guido van Rossum21142a01999-01-08 21:05:37 +00003044#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003045/*[clinic input]
3046os.fsync
3047
3048 fd: fildes
3049
3050Force write of fd to disk.
3051[clinic start generated code]*/
3052
Larry Hastings2f936352014-08-05 14:04:04 +10003053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003054os_fsync_impl(PyObject *module, int fd)
3055/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003056{
3057 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003058}
3059#endif /* HAVE_FSYNC */
3060
Larry Hastings2f936352014-08-05 14:04:04 +10003061
Ross Lagerwall7807c352011-03-17 20:20:30 +02003062#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003063/*[clinic input]
3064os.sync
3065
3066Force write of everything to disk.
3067[clinic start generated code]*/
3068
Larry Hastings2f936352014-08-05 14:04:04 +10003069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003070os_sync_impl(PyObject *module)
3071/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003072{
3073 Py_BEGIN_ALLOW_THREADS
3074 sync();
3075 Py_END_ALLOW_THREADS
3076 Py_RETURN_NONE;
3077}
Larry Hastings2f936352014-08-05 14:04:04 +10003078#endif /* HAVE_SYNC */
3079
Ross Lagerwall7807c352011-03-17 20:20:30 +02003080
Guido van Rossum21142a01999-01-08 21:05:37 +00003081#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003082#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003083extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3084#endif
3085
Larry Hastings2f936352014-08-05 14:04:04 +10003086/*[clinic input]
3087os.fdatasync
3088
3089 fd: fildes
3090
3091Force write of fd to disk without forcing update of metadata.
3092[clinic start generated code]*/
3093
Larry Hastings2f936352014-08-05 14:04:04 +10003094static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003095os_fdatasync_impl(PyObject *module, int fd)
3096/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003097{
3098 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003099}
3100#endif /* HAVE_FDATASYNC */
3101
3102
Fredrik Lundh10723342000-07-10 16:38:09 +00003103#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003104/*[clinic input]
3105os.chown
3106
3107 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3108 Path to be examined; can be string, bytes, or open-file-descriptor int.
3109
3110 uid: uid_t
3111
3112 gid: gid_t
3113
3114 *
3115
3116 dir_fd : dir_fd(requires='fchownat') = None
3117 If not None, it should be a file descriptor open to a directory,
3118 and path should be relative; path will then be relative to that
3119 directory.
3120
3121 follow_symlinks: bool = True
3122 If False, and the last element of the path is a symbolic link,
3123 stat will examine the symbolic link itself instead of the file
3124 the link points to.
3125
3126Change the owner and group id of path to the numeric uid and gid.\
3127
3128path may always be specified as a string.
3129On some platforms, path may also be specified as an open file descriptor.
3130 If this functionality is unavailable, using it raises an exception.
3131If dir_fd is not None, it should be a file descriptor open to a directory,
3132 and path should be relative; path will then be relative to that directory.
3133If follow_symlinks is False, and the last element of the path is a symbolic
3134 link, chown will modify the symbolic link itself instead of the file the
3135 link points to.
3136It is an error to use dir_fd or follow_symlinks when specifying path as
3137 an open file descriptor.
3138dir_fd and follow_symlinks may not be implemented on your platform.
3139 If they are unavailable, using them will raise a NotImplementedError.
3140
3141[clinic start generated code]*/
3142
Larry Hastings2f936352014-08-05 14:04:04 +10003143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003144os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003145 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003146/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003147{
3148 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149
3150#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3151 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003152 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003154 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3155 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3156 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157
3158#ifdef __APPLE__
3159 /*
3160 * This is for Mac OS X 10.3, which doesn't have lchown.
3161 * (But we still have an lchown symbol because of weak-linking.)
3162 * It doesn't have fchownat either. So there's no possibility
3163 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003164 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003165 if ((!follow_symlinks) && (lchown == NULL)) {
3166 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003167 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003168 }
3169#endif
3170
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003173 if (path->fd != -1)
3174 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175 else
3176#endif
3177#ifdef HAVE_LCHOWN
3178 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003179 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003180 else
3181#endif
3182#ifdef HAVE_FCHOWNAT
3183 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003184 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003185 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3186 else
3187#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003188 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003190
Larry Hastings2f936352014-08-05 14:04:04 +10003191 if (result)
3192 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003193
Larry Hastings2f936352014-08-05 14:04:04 +10003194 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003195}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003196#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003197
Larry Hastings2f936352014-08-05 14:04:04 +10003198
Christian Heimes4e30a842007-11-30 22:12:06 +00003199#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003200/*[clinic input]
3201os.fchown
3202
3203 fd: int
3204 uid: uid_t
3205 gid: gid_t
3206
3207Change the owner and group id of the file specified by file descriptor.
3208
3209Equivalent to os.chown(fd, uid, gid).
3210
3211[clinic start generated code]*/
3212
Larry Hastings2f936352014-08-05 14:04:04 +10003213static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003214os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3215/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003216{
Victor Stinner8c62be82010-05-06 00:08:46 +00003217 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003218 int async_err = 0;
3219
3220 do {
3221 Py_BEGIN_ALLOW_THREADS
3222 res = fchown(fd, uid, gid);
3223 Py_END_ALLOW_THREADS
3224 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3225 if (res != 0)
3226 return (!async_err) ? posix_error() : NULL;
3227
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003229}
3230#endif /* HAVE_FCHOWN */
3231
Larry Hastings2f936352014-08-05 14:04:04 +10003232
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003233#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003234/*[clinic input]
3235os.lchown
3236
3237 path : path_t
3238 uid: uid_t
3239 gid: gid_t
3240
3241Change the owner and group id of path to the numeric uid and gid.
3242
3243This function will not follow symbolic links.
3244Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3245[clinic start generated code]*/
3246
Larry Hastings2f936352014-08-05 14:04:04 +10003247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003248os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3249/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003250{
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003253 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003255 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003256 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003257 }
Larry Hastings2f936352014-08-05 14:04:04 +10003258 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003259}
3260#endif /* HAVE_LCHOWN */
3261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003262
Barry Warsaw53699e91996-12-10 23:23:01 +00003263static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003264posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003265{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003266 char *buf, *tmpbuf;
3267 char *cwd;
3268 const size_t chunk = 1024;
3269 size_t buflen = 0;
3270 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003271
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003272#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003273 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003274 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 wchar_t *wbuf2 = wbuf;
3276 PyObject *resobj;
3277 DWORD len;
3278 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003279 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 /* If the buffer is large enough, len does not include the
3281 terminating \0. If the buffer is too small, len includes
3282 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003283 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003284 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 if (wbuf2)
3286 len = GetCurrentDirectoryW(len, wbuf2);
3287 }
3288 Py_END_ALLOW_THREADS
3289 if (!wbuf2) {
3290 PyErr_NoMemory();
3291 return NULL;
3292 }
3293 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003294 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003295 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003296 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003297 }
3298 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003299 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003300 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 return resobj;
3302 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003303
3304 if (win32_warn_bytes_api())
3305 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003306#endif
3307
Victor Stinner4403d7d2015-04-25 00:16:10 +02003308 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003309 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003310 do {
3311 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003312#ifdef MS_WINDOWS
3313 if (buflen > INT_MAX) {
3314 PyErr_NoMemory();
3315 break;
3316 }
3317#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003318 tmpbuf = PyMem_RawRealloc(buf, buflen);
3319 if (tmpbuf == NULL)
3320 break;
3321
3322 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003323#ifdef MS_WINDOWS
3324 cwd = getcwd(buf, (int)buflen);
3325#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003326 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003327#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003328 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003329 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003330
3331 if (cwd == NULL) {
3332 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003334 }
3335
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003337 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3338 else
3339 obj = PyUnicode_DecodeFSDefault(buf);
3340 PyMem_RawFree(buf);
3341
3342 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003343}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003344
Larry Hastings2f936352014-08-05 14:04:04 +10003345
3346/*[clinic input]
3347os.getcwd
3348
3349Return a unicode string representing the current working directory.
3350[clinic start generated code]*/
3351
Larry Hastings2f936352014-08-05 14:04:04 +10003352static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003353os_getcwd_impl(PyObject *module)
3354/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003355{
3356 return posix_getcwd(0);
3357}
3358
Larry Hastings2f936352014-08-05 14:04:04 +10003359
3360/*[clinic input]
3361os.getcwdb
3362
3363Return a bytes string representing the current working directory.
3364[clinic start generated code]*/
3365
Larry Hastings2f936352014-08-05 14:04:04 +10003366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003367os_getcwdb_impl(PyObject *module)
3368/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003369{
3370 return posix_getcwd(1);
3371}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003372
Larry Hastings2f936352014-08-05 14:04:04 +10003373
Larry Hastings9cf065c2012-06-22 16:30:09 -07003374#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3375#define HAVE_LINK 1
3376#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003377
Guido van Rossumb6775db1994-08-01 11:34:53 +00003378#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003379/*[clinic input]
3380
3381os.link
3382
3383 src : path_t
3384 dst : path_t
3385 *
3386 src_dir_fd : dir_fd = None
3387 dst_dir_fd : dir_fd = None
3388 follow_symlinks: bool = True
3389
3390Create a hard link to a file.
3391
3392If either src_dir_fd or dst_dir_fd is not None, it should be a file
3393 descriptor open to a directory, and the respective path string (src or dst)
3394 should be relative; the path will then be relative to that directory.
3395If follow_symlinks is False, and the last element of src is a symbolic
3396 link, link will create a link to the symbolic link itself instead of the
3397 file the link points to.
3398src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3399 platform. If they are unavailable, using them will raise a
3400 NotImplementedError.
3401[clinic start generated code]*/
3402
Larry Hastings2f936352014-08-05 14:04:04 +10003403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003404os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003405 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003406/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003407{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003409 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410#else
3411 int result;
3412#endif
3413
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414#ifndef HAVE_LINKAT
3415 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3416 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003417 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003418 }
3419#endif
3420
Steve Dowercc16be82016-09-08 10:35:16 -07003421#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003422 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 PyErr_SetString(PyExc_NotImplementedError,
3424 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003425 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 }
Steve Dowercc16be82016-09-08 10:35:16 -07003427#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003428
Brian Curtin1b9df392010-11-24 20:24:31 +00003429#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003431 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if (!result)
3435 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436#else
3437 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003438#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3440 (dst_dir_fd != DEFAULT_DIR_FD) ||
3441 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003442 result = linkat(src_dir_fd, src->narrow,
3443 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3445 else
Steve Dowercc16be82016-09-08 10:35:16 -07003446#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003447 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003449
Larry Hastings2f936352014-08-05 14:04:04 +10003450 if (result)
3451 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003452#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453
Larry Hastings2f936352014-08-05 14:04:04 +10003454 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003455}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456#endif
3457
Brian Curtin1b9df392010-11-24 20:24:31 +00003458
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003459#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003460static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003461_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003462{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 PyObject *v;
3464 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3465 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003466 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003468 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470
Steve Dowercc16be82016-09-08 10:35:16 -07003471 WIN32_FIND_DATAW wFileData;
3472 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003473
Steve Dowercc16be82016-09-08 10:35:16 -07003474 if (!path->wide) { /* Default arg: "." */
3475 po_wchars = L".";
3476 len = 1;
3477 } else {
3478 po_wchars = path->wide;
3479 len = wcslen(path->wide);
3480 }
3481 /* The +5 is so we can append "\\*.*\0" */
3482 wnamebuf = PyMem_New(wchar_t, len + 5);
3483 if (!wnamebuf) {
3484 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 }
Steve Dowercc16be82016-09-08 10:35:16 -07003487 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003489 wchar_t wch = wnamebuf[len-1];
3490 if (wch != SEP && wch != ALTSEP && wch != L':')
3491 wnamebuf[len++] = SEP;
3492 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003493 }
Steve Dowercc16be82016-09-08 10:35:16 -07003494 if ((list = PyList_New(0)) == NULL) {
3495 goto exit;
3496 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003497 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003498 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003499 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 if (hFindFile == INVALID_HANDLE_VALUE) {
3501 int error = GetLastError();
3502 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 goto exit;
3504 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003505 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 }
3508 do {
3509 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003510 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3511 wcscmp(wFileData.cFileName, L"..") != 0) {
3512 v = PyUnicode_FromWideChar(wFileData.cFileName,
3513 wcslen(wFileData.cFileName));
3514 if (path->narrow && v) {
3515 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3516 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 Py_DECREF(list);
3519 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 break;
3521 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 Py_DECREF(list);
3525 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003526 break;
3527 }
3528 Py_DECREF(v);
3529 }
3530 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003531 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 Py_END_ALLOW_THREADS
3533 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3534 it got to the end of the directory. */
3535 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003537 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 }
3540 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003541
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542exit:
3543 if (hFindFile != INVALID_HANDLE_VALUE) {
3544 if (FindClose(hFindFile) == FALSE) {
3545 if (list != NULL) {
3546 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003547 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548 }
3549 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003551 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003552
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003554} /* end of _listdir_windows_no_opendir */
3555
3556#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3557
3558static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003559_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003560{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003561 PyObject *v;
3562 DIR *dirp = NULL;
3563 struct dirent *ep;
3564 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003565#ifdef HAVE_FDOPENDIR
3566 int fd = -1;
3567#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003568
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003571 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003573 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003574 if (fd == -1)
3575 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576
Larry Hastingsfdaea062012-06-25 04:42:23 -07003577 return_str = 1;
3578
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 Py_BEGIN_ALLOW_THREADS
3580 dirp = fdopendir(fd);
3581 Py_END_ALLOW_THREADS
3582 }
3583 else
3584#endif
3585 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003586 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003587 if (path->narrow) {
3588 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003589 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003590 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003591 }
3592 else {
3593 name = ".";
3594 return_str = 1;
3595 }
3596
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597 Py_BEGIN_ALLOW_THREADS
3598 dirp = opendir(name);
3599 Py_END_ALLOW_THREADS
3600 }
3601
3602 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003603 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003604#ifdef HAVE_FDOPENDIR
3605 if (fd != -1) {
3606 Py_BEGIN_ALLOW_THREADS
3607 close(fd);
3608 Py_END_ALLOW_THREADS
3609 }
3610#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 goto exit;
3612 }
3613 if ((list = PyList_New(0)) == NULL) {
3614 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003615 }
3616 for (;;) {
3617 errno = 0;
3618 Py_BEGIN_ALLOW_THREADS
3619 ep = readdir(dirp);
3620 Py_END_ALLOW_THREADS
3621 if (ep == NULL) {
3622 if (errno == 0) {
3623 break;
3624 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003626 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 }
3629 }
3630 if (ep->d_name[0] == '.' &&
3631 (NAMLEN(ep) == 1 ||
3632 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3633 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003634 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003635 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3636 else
3637 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003639 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 break;
3641 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 break;
3646 }
3647 Py_DECREF(v);
3648 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003649
Larry Hastings9cf065c2012-06-22 16:30:09 -07003650exit:
3651 if (dirp != NULL) {
3652 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003653#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 if (fd > -1)
3655 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003656#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657 closedir(dirp);
3658 Py_END_ALLOW_THREADS
3659 }
3660
Larry Hastings9cf065c2012-06-22 16:30:09 -07003661 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003662} /* end of _posix_listdir */
3663#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003664
Larry Hastings2f936352014-08-05 14:04:04 +10003665
3666/*[clinic input]
3667os.listdir
3668
3669 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3670
3671Return a list containing the names of the files in the directory.
3672
3673path can be specified as either str or bytes. If path is bytes,
3674 the filenames returned will also be bytes; in all other circumstances
3675 the filenames returned will be str.
3676If path is None, uses the path='.'.
3677On some platforms, path may also be specified as an open file descriptor;\
3678 the file descriptor must refer to a directory.
3679 If this functionality is unavailable, using it raises NotImplementedError.
3680
3681The list is in arbitrary order. It does not include the special
3682entries '.' and '..' even if they are present in the directory.
3683
3684
3685[clinic start generated code]*/
3686
Larry Hastings2f936352014-08-05 14:04:04 +10003687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003688os_listdir_impl(PyObject *module, path_t *path)
3689/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003690{
3691#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3692 return _listdir_windows_no_opendir(path, NULL);
3693#else
3694 return _posix_listdir(path, NULL);
3695#endif
3696}
3697
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003698#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003699/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003700/*[clinic input]
3701os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003702
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003703 path: path_t
3704 /
3705
3706[clinic start generated code]*/
3707
3708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003709os__getfullpathname_impl(PyObject *module, path_t *path)
3710/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003711{
Steve Dowercc16be82016-09-08 10:35:16 -07003712 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3713 wchar_t *wtemp;
3714 DWORD result;
3715 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003716
Steve Dowercc16be82016-09-08 10:35:16 -07003717 result = GetFullPathNameW(path->wide,
3718 Py_ARRAY_LENGTH(woutbuf),
3719 woutbuf, &wtemp);
3720 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3721 woutbufp = PyMem_New(wchar_t, result);
3722 if (!woutbufp)
3723 return PyErr_NoMemory();
3724 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003725 }
Steve Dowercc16be82016-09-08 10:35:16 -07003726 if (result) {
3727 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3728 if (path->narrow)
3729 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3730 } else
3731 v = win32_error_object("GetFullPathNameW", path->object);
3732 if (woutbufp != woutbuf)
3733 PyMem_Free(woutbufp);
3734 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003735}
Brian Curtind40e6f72010-07-08 21:39:08 +00003736
Brian Curtind25aef52011-06-13 15:16:04 -05003737
Larry Hastings2f936352014-08-05 14:04:04 +10003738/*[clinic input]
3739os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003740
Larry Hastings2f936352014-08-05 14:04:04 +10003741 path: unicode
3742 /
3743
3744A helper function for samepath on windows.
3745[clinic start generated code]*/
3746
Larry Hastings2f936352014-08-05 14:04:04 +10003747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003748os__getfinalpathname_impl(PyObject *module, PyObject *path)
3749/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003750{
3751 HANDLE hFile;
3752 int buf_size;
3753 wchar_t *target_path;
3754 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003755 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003756 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003757
Larry Hastings2f936352014-08-05 14:04:04 +10003758 path_wchar = PyUnicode_AsUnicode(path);
3759 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003760 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003761
Brian Curtind40e6f72010-07-08 21:39:08 +00003762 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003763 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003764 0, /* desired access */
3765 0, /* share mode */
3766 NULL, /* security attributes */
3767 OPEN_EXISTING,
3768 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3769 FILE_FLAG_BACKUP_SEMANTICS,
3770 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003771
Victor Stinnereb5657a2011-09-30 01:44:27 +02003772 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003773 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003774
3775 /* We have a good handle to the target, use it to determine the
3776 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003777 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003778
3779 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003780 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003781
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003782 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003783 if(!target_path)
3784 return PyErr_NoMemory();
3785
Steve Dower2ea51c92015-03-20 21:49:12 -07003786 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3787 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003788 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003789 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003790
3791 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003792 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003793
3794 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003795 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003796 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003797 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003798}
Brian Curtin62857742010-09-06 17:07:27 +00003799
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003800/*[clinic input]
3801os._isdir
3802
3803 path: path_t
3804 /
3805
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003806Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003807[clinic start generated code]*/
3808
Brian Curtin9c669cc2011-06-08 18:17:18 -05003809static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003810os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003811/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003812{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003813 DWORD attributes;
3814
Steve Dowerb22a6772016-07-17 20:49:38 -07003815 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003816 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003817 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003818
Brian Curtin9c669cc2011-06-08 18:17:18 -05003819 if (attributes == INVALID_FILE_ATTRIBUTES)
3820 Py_RETURN_FALSE;
3821
Brian Curtin9c669cc2011-06-08 18:17:18 -05003822 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3823 Py_RETURN_TRUE;
3824 else
3825 Py_RETURN_FALSE;
3826}
Tim Golden6b528062013-08-01 12:44:00 +01003827
Tim Golden6b528062013-08-01 12:44:00 +01003828
Larry Hastings2f936352014-08-05 14:04:04 +10003829/*[clinic input]
3830os._getvolumepathname
3831
3832 path: unicode
3833
3834A helper function for ismount on Win32.
3835[clinic start generated code]*/
3836
Larry Hastings2f936352014-08-05 14:04:04 +10003837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003838os__getvolumepathname_impl(PyObject *module, PyObject *path)
3839/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003840{
3841 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003842 const wchar_t *path_wchar;
3843 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003844 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003845 BOOL ret;
3846
Larry Hastings2f936352014-08-05 14:04:04 +10003847 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3848 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003849 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003850 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003851
3852 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003853 buflen = Py_MAX(buflen, MAX_PATH);
3854
3855 if (buflen > DWORD_MAX) {
3856 PyErr_SetString(PyExc_OverflowError, "path too long");
3857 return NULL;
3858 }
3859
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003860 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003861 if (mountpath == NULL)
3862 return PyErr_NoMemory();
3863
3864 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003865 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003866 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003867 Py_END_ALLOW_THREADS
3868
3869 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003870 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003871 goto exit;
3872 }
3873 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3874
3875exit:
3876 PyMem_Free(mountpath);
3877 return result;
3878}
Tim Golden6b528062013-08-01 12:44:00 +01003879
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003880#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003881
Larry Hastings2f936352014-08-05 14:04:04 +10003882
3883/*[clinic input]
3884os.mkdir
3885
3886 path : path_t
3887
3888 mode: int = 0o777
3889
3890 *
3891
3892 dir_fd : dir_fd(requires='mkdirat') = None
3893
3894# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3895
3896Create a directory.
3897
3898If dir_fd is not None, it should be a file descriptor open to a directory,
3899 and path should be relative; path will then be relative to that directory.
3900dir_fd may not be implemented on your platform.
3901 If it is unavailable, using it will raise a NotImplementedError.
3902
3903The mode argument is ignored on Windows.
3904[clinic start generated code]*/
3905
Larry Hastings2f936352014-08-05 14:04:04 +10003906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003907os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3908/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003909{
3910 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003911
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003912#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003914 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003916
Larry Hastings2f936352014-08-05 14:04:04 +10003917 if (!result)
3918 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003921#if HAVE_MKDIRAT
3922 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003923 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003924 else
3925#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003926#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003927 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003928#else
Larry Hastings2f936352014-08-05 14:04:04 +10003929 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003930#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003931 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003932 if (result < 0)
3933 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003934#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003935 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003936}
3937
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003938
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003939/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3940#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003941#include <sys/resource.h>
3942#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003943
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003944
3945#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003946/*[clinic input]
3947os.nice
3948
3949 increment: int
3950 /
3951
3952Add increment to the priority of process and return the new priority.
3953[clinic start generated code]*/
3954
Larry Hastings2f936352014-08-05 14:04:04 +10003955static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003956os_nice_impl(PyObject *module, int increment)
3957/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003958{
3959 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003960
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 /* There are two flavours of 'nice': one that returns the new
3962 priority (as required by almost all standards out there) and the
3963 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3964 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003965
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 If we are of the nice family that returns the new priority, we
3967 need to clear errno before the call, and check if errno is filled
3968 before calling posix_error() on a returnvalue of -1, because the
3969 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003970
Victor Stinner8c62be82010-05-06 00:08:46 +00003971 errno = 0;
3972 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003973#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003974 if (value == 0)
3975 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003976#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003977 if (value == -1 && errno != 0)
3978 /* either nice() or getpriority() returned an error */
3979 return posix_error();
3980 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003981}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003982#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003983
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003984
3985#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003986/*[clinic input]
3987os.getpriority
3988
3989 which: int
3990 who: int
3991
3992Return program scheduling priority.
3993[clinic start generated code]*/
3994
Larry Hastings2f936352014-08-05 14:04:04 +10003995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003996os_getpriority_impl(PyObject *module, int which, int who)
3997/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003998{
3999 int retval;
4000
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004001 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004002 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004003 if (errno != 0)
4004 return posix_error();
4005 return PyLong_FromLong((long)retval);
4006}
4007#endif /* HAVE_GETPRIORITY */
4008
4009
4010#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004011/*[clinic input]
4012os.setpriority
4013
4014 which: int
4015 who: int
4016 priority: int
4017
4018Set program scheduling priority.
4019[clinic start generated code]*/
4020
Larry Hastings2f936352014-08-05 14:04:04 +10004021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004022os_setpriority_impl(PyObject *module, int which, int who, int priority)
4023/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004024{
4025 int retval;
4026
4027 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004028 if (retval == -1)
4029 return posix_error();
4030 Py_RETURN_NONE;
4031}
4032#endif /* HAVE_SETPRIORITY */
4033
4034
Barry Warsaw53699e91996-12-10 23:23:01 +00004035static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004036internal_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 +00004037{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004038 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004039 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004041#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004042 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004043 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004044#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004045 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004046#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047
Larry Hastings9cf065c2012-06-22 16:30:09 -07004048 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4049 (dst_dir_fd != DEFAULT_DIR_FD);
4050#ifndef HAVE_RENAMEAT
4051 if (dir_fd_specified) {
4052 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004053 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004054 }
4055#endif
4056
Larry Hastings9cf065c2012-06-22 16:30:09 -07004057#ifdef MS_WINDOWS
4058 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004059 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004060 Py_END_ALLOW_THREADS
4061
Larry Hastings2f936352014-08-05 14:04:04 +10004062 if (!result)
4063 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004064
4065#else
Steve Dowercc16be82016-09-08 10:35:16 -07004066 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4067 PyErr_Format(PyExc_ValueError,
4068 "%s: src and dst must be the same type", function_name);
4069 return NULL;
4070 }
4071
Larry Hastings9cf065c2012-06-22 16:30:09 -07004072 Py_BEGIN_ALLOW_THREADS
4073#ifdef HAVE_RENAMEAT
4074 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004075 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076 else
4077#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004078 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079 Py_END_ALLOW_THREADS
4080
Larry Hastings2f936352014-08-05 14:04:04 +10004081 if (result)
4082 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004084 Py_RETURN_NONE;
4085}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086
Larry Hastings2f936352014-08-05 14:04:04 +10004087
4088/*[clinic input]
4089os.rename
4090
4091 src : path_t
4092 dst : path_t
4093 *
4094 src_dir_fd : dir_fd = None
4095 dst_dir_fd : dir_fd = None
4096
4097Rename a file or directory.
4098
4099If either src_dir_fd or dst_dir_fd is not None, it should be a file
4100 descriptor open to a directory, and the respective path string (src or dst)
4101 should be relative; the path will then be relative to that directory.
4102src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4103 If they are unavailable, using them will raise a NotImplementedError.
4104[clinic start generated code]*/
4105
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004107os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004108 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004109/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004110{
Larry Hastings2f936352014-08-05 14:04:04 +10004111 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004112}
4113
Larry Hastings2f936352014-08-05 14:04:04 +10004114
4115/*[clinic input]
4116os.replace = os.rename
4117
4118Rename a file or directory, overwriting the destination.
4119
4120If either src_dir_fd or dst_dir_fd is not None, it should be a file
4121 descriptor open to a directory, and the respective path string (src or dst)
4122 should be relative; the path will then be relative to that directory.
4123src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4124 If they are unavailable, using them will raise a NotImplementedError."
4125[clinic start generated code]*/
4126
Larry Hastings2f936352014-08-05 14:04:04 +10004127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004128os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4129 int dst_dir_fd)
4130/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004131{
4132 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4133}
4134
4135
4136/*[clinic input]
4137os.rmdir
4138
4139 path: path_t
4140 *
4141 dir_fd: dir_fd(requires='unlinkat') = None
4142
4143Remove a directory.
4144
4145If dir_fd is not None, it should be a file descriptor open to a directory,
4146 and path should be relative; path will then be relative to that directory.
4147dir_fd may not be implemented on your platform.
4148 If it is unavailable, using it will raise a NotImplementedError.
4149[clinic start generated code]*/
4150
Larry Hastings2f936352014-08-05 14:04:04 +10004151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004152os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4153/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004154{
4155 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004156
4157 Py_BEGIN_ALLOW_THREADS
4158#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004159 /* Windows, success=1, UNIX, success=0 */
4160 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004161#else
4162#ifdef HAVE_UNLINKAT
4163 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004164 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004165 else
4166#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004167 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004168#endif
4169 Py_END_ALLOW_THREADS
4170
Larry Hastings2f936352014-08-05 14:04:04 +10004171 if (result)
4172 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004173
Larry Hastings2f936352014-08-05 14:04:04 +10004174 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004175}
4176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004177
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004178#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004179#ifdef MS_WINDOWS
4180/*[clinic input]
4181os.system -> long
4182
4183 command: Py_UNICODE
4184
4185Execute the command in a subshell.
4186[clinic start generated code]*/
4187
Larry Hastings2f936352014-08-05 14:04:04 +10004188static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004189os_system_impl(PyObject *module, Py_UNICODE *command)
4190/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004191{
4192 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004193 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004194 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004195 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004196 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004197 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004198 return result;
4199}
4200#else /* MS_WINDOWS */
4201/*[clinic input]
4202os.system -> long
4203
4204 command: FSConverter
4205
4206Execute the command in a subshell.
4207[clinic start generated code]*/
4208
Larry Hastings2f936352014-08-05 14:04:04 +10004209static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004210os_system_impl(PyObject *module, PyObject *command)
4211/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004212{
4213 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004214 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004215 Py_BEGIN_ALLOW_THREADS
4216 result = system(bytes);
4217 Py_END_ALLOW_THREADS
4218 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004219}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004220#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004221#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004223
Larry Hastings2f936352014-08-05 14:04:04 +10004224/*[clinic input]
4225os.umask
4226
4227 mask: int
4228 /
4229
4230Set the current numeric umask and return the previous umask.
4231[clinic start generated code]*/
4232
Larry Hastings2f936352014-08-05 14:04:04 +10004233static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004234os_umask_impl(PyObject *module, int mask)
4235/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004236{
4237 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004238 if (i < 0)
4239 return posix_error();
4240 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004241}
4242
Brian Curtind40e6f72010-07-08 21:39:08 +00004243#ifdef MS_WINDOWS
4244
4245/* override the default DeleteFileW behavior so that directory
4246symlinks can be removed with this function, the same as with
4247Unix symlinks */
4248BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4249{
4250 WIN32_FILE_ATTRIBUTE_DATA info;
4251 WIN32_FIND_DATAW find_data;
4252 HANDLE find_data_handle;
4253 int is_directory = 0;
4254 int is_link = 0;
4255
4256 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4257 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004258
Brian Curtind40e6f72010-07-08 21:39:08 +00004259 /* Get WIN32_FIND_DATA structure for the path to determine if
4260 it is a symlink */
4261 if(is_directory &&
4262 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4263 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4264
4265 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004266 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4267 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4268 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4269 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004270 FindClose(find_data_handle);
4271 }
4272 }
4273 }
4274
4275 if (is_directory && is_link)
4276 return RemoveDirectoryW(lpFileName);
4277
4278 return DeleteFileW(lpFileName);
4279}
4280#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004282
Larry Hastings2f936352014-08-05 14:04:04 +10004283/*[clinic input]
4284os.unlink
4285
4286 path: path_t
4287 *
4288 dir_fd: dir_fd(requires='unlinkat')=None
4289
4290Remove a file (same as remove()).
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
4297[clinic start generated code]*/
4298
Larry Hastings2f936352014-08-05 14:04:04 +10004299static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004300os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4301/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004302{
4303 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004304
4305 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004306 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004307#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004308 /* Windows, success=1, UNIX, success=0 */
4309 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004310#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004311#ifdef HAVE_UNLINKAT
4312 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004313 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004314 else
4315#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004316 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004318 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004319 Py_END_ALLOW_THREADS
4320
Larry Hastings2f936352014-08-05 14:04:04 +10004321 if (result)
4322 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004323
Larry Hastings2f936352014-08-05 14:04:04 +10004324 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004325}
4326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004327
Larry Hastings2f936352014-08-05 14:04:04 +10004328/*[clinic input]
4329os.remove = os.unlink
4330
4331Remove a file (same as unlink()).
4332
4333If dir_fd is not None, it should be a file descriptor open to a directory,
4334 and path should be relative; path will then be relative to that directory.
4335dir_fd may not be implemented on your platform.
4336 If it is unavailable, using it will raise a NotImplementedError.
4337[clinic start generated code]*/
4338
Larry Hastings2f936352014-08-05 14:04:04 +10004339static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004340os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4341/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004342{
4343 return os_unlink_impl(module, path, dir_fd);
4344}
4345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004346
Larry Hastings605a62d2012-06-24 04:33:36 -07004347static PyStructSequence_Field uname_result_fields[] = {
4348 {"sysname", "operating system name"},
4349 {"nodename", "name of machine on network (implementation-defined)"},
4350 {"release", "operating system release"},
4351 {"version", "operating system version"},
4352 {"machine", "hardware identifier"},
4353 {NULL}
4354};
4355
4356PyDoc_STRVAR(uname_result__doc__,
4357"uname_result: Result from os.uname().\n\n\
4358This object may be accessed either as a tuple of\n\
4359 (sysname, nodename, release, version, machine),\n\
4360or via the attributes sysname, nodename, release, version, and machine.\n\
4361\n\
4362See os.uname for more information.");
4363
4364static PyStructSequence_Desc uname_result_desc = {
4365 "uname_result", /* name */
4366 uname_result__doc__, /* doc */
4367 uname_result_fields,
4368 5
4369};
4370
4371static PyTypeObject UnameResultType;
4372
4373
4374#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004375/*[clinic input]
4376os.uname
4377
4378Return an object identifying the current operating system.
4379
4380The object behaves like a named tuple with the following fields:
4381 (sysname, nodename, release, version, machine)
4382
4383[clinic start generated code]*/
4384
Larry Hastings2f936352014-08-05 14:04:04 +10004385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004386os_uname_impl(PyObject *module)
4387/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004388{
Victor Stinner8c62be82010-05-06 00:08:46 +00004389 struct utsname u;
4390 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004391 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004392
Victor Stinner8c62be82010-05-06 00:08:46 +00004393 Py_BEGIN_ALLOW_THREADS
4394 res = uname(&u);
4395 Py_END_ALLOW_THREADS
4396 if (res < 0)
4397 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004398
4399 value = PyStructSequence_New(&UnameResultType);
4400 if (value == NULL)
4401 return NULL;
4402
4403#define SET(i, field) \
4404 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004405 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004406 if (!o) { \
4407 Py_DECREF(value); \
4408 return NULL; \
4409 } \
4410 PyStructSequence_SET_ITEM(value, i, o); \
4411 } \
4412
4413 SET(0, u.sysname);
4414 SET(1, u.nodename);
4415 SET(2, u.release);
4416 SET(3, u.version);
4417 SET(4, u.machine);
4418
4419#undef SET
4420
4421 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004422}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004423#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004424
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004425
Larry Hastings9cf065c2012-06-22 16:30:09 -07004426
4427typedef struct {
4428 int now;
4429 time_t atime_s;
4430 long atime_ns;
4431 time_t mtime_s;
4432 long mtime_ns;
4433} utime_t;
4434
4435/*
Victor Stinner484df002014-10-09 13:52:31 +02004436 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004437 * they also intentionally leak the declaration of a pointer named "time"
4438 */
4439#define UTIME_TO_TIMESPEC \
4440 struct timespec ts[2]; \
4441 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004442 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004443 time = NULL; \
4444 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004445 ts[0].tv_sec = ut->atime_s; \
4446 ts[0].tv_nsec = ut->atime_ns; \
4447 ts[1].tv_sec = ut->mtime_s; \
4448 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004449 time = ts; \
4450 } \
4451
4452#define UTIME_TO_TIMEVAL \
4453 struct timeval tv[2]; \
4454 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004455 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456 time = NULL; \
4457 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004458 tv[0].tv_sec = ut->atime_s; \
4459 tv[0].tv_usec = ut->atime_ns / 1000; \
4460 tv[1].tv_sec = ut->mtime_s; \
4461 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004462 time = tv; \
4463 } \
4464
4465#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004466 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004467 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004468 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 time = NULL; \
4470 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004471 u.actime = ut->atime_s; \
4472 u.modtime = ut->mtime_s; \
4473 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004474 }
4475
4476#define UTIME_TO_TIME_T \
4477 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004478 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004479 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480 time = NULL; \
4481 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004482 timet[0] = ut->atime_s; \
4483 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004484 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004485 } \
4486
4487
Victor Stinner528a9ab2015-09-03 21:30:26 +02004488#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004489
4490static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004491utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492{
4493#ifdef HAVE_UTIMENSAT
4494 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4495 UTIME_TO_TIMESPEC;
4496 return utimensat(dir_fd, path, time, flags);
4497#elif defined(HAVE_FUTIMESAT)
4498 UTIME_TO_TIMEVAL;
4499 /*
4500 * follow_symlinks will never be false here;
4501 * we only allow !follow_symlinks and dir_fd together
4502 * if we have utimensat()
4503 */
4504 assert(follow_symlinks);
4505 return futimesat(dir_fd, path, time);
4506#endif
4507}
4508
Larry Hastings2f936352014-08-05 14:04:04 +10004509 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4510#else
4511 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004512#endif
4513
Victor Stinner528a9ab2015-09-03 21:30:26 +02004514#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004515
4516static int
Victor Stinner484df002014-10-09 13:52:31 +02004517utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518{
4519#ifdef HAVE_FUTIMENS
4520 UTIME_TO_TIMESPEC;
4521 return futimens(fd, time);
4522#else
4523 UTIME_TO_TIMEVAL;
4524 return futimes(fd, time);
4525#endif
4526}
4527
Larry Hastings2f936352014-08-05 14:04:04 +10004528 #define PATH_UTIME_HAVE_FD 1
4529#else
4530 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531#endif
4532
Victor Stinner5ebae872015-09-22 01:29:33 +02004533#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4534# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4535#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536
Victor Stinner4552ced2015-09-21 22:37:15 +02004537#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538
4539static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004540utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541{
4542#ifdef HAVE_UTIMENSAT
4543 UTIME_TO_TIMESPEC;
4544 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4545#else
4546 UTIME_TO_TIMEVAL;
4547 return lutimes(path, time);
4548#endif
4549}
4550
4551#endif
4552
4553#ifndef MS_WINDOWS
4554
4555static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004556utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004557{
4558#ifdef HAVE_UTIMENSAT
4559 UTIME_TO_TIMESPEC;
4560 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4561#elif defined(HAVE_UTIMES)
4562 UTIME_TO_TIMEVAL;
4563 return utimes(path, time);
4564#elif defined(HAVE_UTIME_H)
4565 UTIME_TO_UTIMBUF;
4566 return utime(path, time);
4567#else
4568 UTIME_TO_TIME_T;
4569 return utime(path, time);
4570#endif
4571}
4572
4573#endif
4574
Larry Hastings76ad59b2012-05-03 00:30:07 -07004575static int
4576split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4577{
4578 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004579 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004580 divmod = PyNumber_Divmod(py_long, billion);
4581 if (!divmod)
4582 goto exit;
4583 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4584 if ((*s == -1) && PyErr_Occurred())
4585 goto exit;
4586 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004587 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004588 goto exit;
4589
4590 result = 1;
4591exit:
4592 Py_XDECREF(divmod);
4593 return result;
4594}
4595
Larry Hastings2f936352014-08-05 14:04:04 +10004596
4597/*[clinic input]
4598os.utime
4599
4600 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4601 times: object = NULL
4602 *
4603 ns: object = NULL
4604 dir_fd: dir_fd(requires='futimensat') = None
4605 follow_symlinks: bool=True
4606
Martin Panter0ff89092015-09-09 01:56:53 +00004607# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004608
4609Set the access and modified time of path.
4610
4611path may always be specified as a string.
4612On some platforms, path may also be specified as an open file descriptor.
4613 If this functionality is unavailable, using it raises an exception.
4614
4615If times is not None, it must be a tuple (atime, mtime);
4616 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004617If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004618 atime_ns and mtime_ns should be expressed as integer nanoseconds
4619 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004620If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004621Specifying tuples for both times and ns is an error.
4622
4623If dir_fd is not None, it should be a file descriptor open to a directory,
4624 and path should be relative; path will then be relative to that directory.
4625If follow_symlinks is False, and the last element of the path is a symbolic
4626 link, utime will modify the symbolic link itself instead of the file the
4627 link points to.
4628It is an error to use dir_fd or follow_symlinks when specifying path
4629 as an open file descriptor.
4630dir_fd and follow_symlinks may not be available on your platform.
4631 If they are unavailable, using them will raise a NotImplementedError.
4632
4633[clinic start generated code]*/
4634
Larry Hastings2f936352014-08-05 14:04:04 +10004635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004636os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4637 int dir_fd, int follow_symlinks)
4638/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004639{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640#ifdef MS_WINDOWS
4641 HANDLE hFile;
4642 FILETIME atime, mtime;
4643#else
4644 int result;
4645#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004646
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004648 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004649
Christian Heimesb3c87242013-08-01 00:08:16 +02004650 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004651
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 if (times && (times != Py_None) && ns) {
4653 PyErr_SetString(PyExc_ValueError,
4654 "utime: you may specify either 'times'"
4655 " or 'ns' but not both");
4656 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004657 }
4658
4659 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004660 time_t a_sec, m_sec;
4661 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004662 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 PyErr_SetString(PyExc_TypeError,
4664 "utime: 'times' must be either"
4665 " a tuple of two ints or None");
4666 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004669 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004670 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004671 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004672 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004674 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004675 utime.atime_s = a_sec;
4676 utime.atime_ns = a_nsec;
4677 utime.mtime_s = m_sec;
4678 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004679 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 PyErr_SetString(PyExc_TypeError,
4683 "utime: 'ns' must be a tuple of two ints");
4684 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004685 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004687 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004689 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 &utime.mtime_s, &utime.mtime_ns)) {
4691 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004692 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 }
4694 else {
4695 /* times and ns are both None/unspecified. use "now". */
4696 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697 }
4698
Victor Stinner4552ced2015-09-21 22:37:15 +02004699#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700 if (follow_symlinks_specified("utime", follow_symlinks))
4701 goto exit;
4702#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004703
Larry Hastings2f936352014-08-05 14:04:04 +10004704 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4705 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4706 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004708
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709#if !defined(HAVE_UTIMENSAT)
4710 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004711 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 "utime: cannot use dir_fd and follow_symlinks "
4713 "together on this platform");
4714 goto exit;
4715 }
4716#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004717
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004718#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004720 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4721 NULL, OPEN_EXISTING,
4722 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004723 Py_END_ALLOW_THREADS
4724 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004725 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004727 }
4728
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004730 GetSystemTimeAsFileTime(&mtime);
4731 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004732 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004734 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4735 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 }
4737 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4738 /* Avoid putting the file name into the error here,
4739 as that may confuse the user into believing that
4740 something is wrong with the file, when it also
4741 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004742 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004745#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004747
Victor Stinner4552ced2015-09-21 22:37:15 +02004748#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004749 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004750 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004752#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753
Victor Stinner528a9ab2015-09-03 21:30:26 +02004754#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004756 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 else
4758#endif
4759
Victor Stinner528a9ab2015-09-03 21:30:26 +02004760#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004761 if (path->fd != -1)
4762 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 else
4764#endif
4765
Larry Hastings2f936352014-08-05 14:04:04 +10004766 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767
4768 Py_END_ALLOW_THREADS
4769
4770 if (result < 0) {
4771 /* see previous comment about not putting filename in error here */
4772 return_value = posix_error();
4773 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004774 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004775
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004776#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004777
4778 Py_INCREF(Py_None);
4779 return_value = Py_None;
4780
4781exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782#ifdef MS_WINDOWS
4783 if (hFile != INVALID_HANDLE_VALUE)
4784 CloseHandle(hFile);
4785#endif
4786 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004787}
4788
Guido van Rossum3b066191991-06-04 19:40:25 +00004789/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004790
Larry Hastings2f936352014-08-05 14:04:04 +10004791
4792/*[clinic input]
4793os._exit
4794
4795 status: int
4796
4797Exit to the system with specified status, without normal exit processing.
4798[clinic start generated code]*/
4799
Larry Hastings2f936352014-08-05 14:04:04 +10004800static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004801os__exit_impl(PyObject *module, int status)
4802/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004803{
4804 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004806}
4807
Steve Dowercc16be82016-09-08 10:35:16 -07004808#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4809#define EXECV_CHAR wchar_t
4810#else
4811#define EXECV_CHAR char
4812#endif
4813
Martin v. Löwis114619e2002-10-07 06:44:21 +00004814#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4815static void
Steve Dowercc16be82016-09-08 10:35:16 -07004816free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004817{
Victor Stinner8c62be82010-05-06 00:08:46 +00004818 Py_ssize_t i;
4819 for (i = 0; i < count; i++)
4820 PyMem_Free(array[i]);
4821 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004822}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004823
Berker Peksag81816462016-09-15 20:19:47 +03004824static int
4825fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004826{
Victor Stinner8c62be82010-05-06 00:08:46 +00004827 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004828 PyObject *ub;
4829 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004830#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004831 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004832 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004833 *out = PyUnicode_AsWideCharString(ub, &size);
4834 if (*out)
4835 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004836#else
Berker Peksag81816462016-09-15 20:19:47 +03004837 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004839 size = PyBytes_GET_SIZE(ub);
4840 *out = PyMem_Malloc(size + 1);
4841 if (*out) {
4842 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4843 result = 1;
4844 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004845 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004846#endif
Berker Peksag81816462016-09-15 20:19:47 +03004847 Py_DECREF(ub);
4848 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004849}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004850#endif
4851
Ross Lagerwall7807c352011-03-17 20:20:30 +02004852#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004853static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004854parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4855{
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 Py_ssize_t i, pos, envc;
4857 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004858 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004859 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004860
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 i = PyMapping_Size(env);
4862 if (i < 0)
4863 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004864 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 if (envlist == NULL) {
4866 PyErr_NoMemory();
4867 return NULL;
4868 }
4869 envc = 0;
4870 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004871 if (!keys)
4872 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004874 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 goto error;
4876 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4877 PyErr_Format(PyExc_TypeError,
4878 "env.keys() or env.values() is not a list");
4879 goto error;
4880 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004881
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 for (pos = 0; pos < i; pos++) {
4883 key = PyList_GetItem(keys, pos);
4884 val = PyList_GetItem(vals, pos);
4885 if (!key || !val)
4886 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004887
Berker Peksag81816462016-09-15 20:19:47 +03004888#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4889 if (!PyUnicode_FSDecoder(key, &key2))
4890 goto error;
4891 if (!PyUnicode_FSDecoder(val, &val2)) {
4892 Py_DECREF(key2);
4893 goto error;
4894 }
4895 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4896#else
4897 if (!PyUnicode_FSConverter(key, &key2))
4898 goto error;
4899 if (!PyUnicode_FSConverter(val, &val2)) {
4900 Py_DECREF(key2);
4901 goto error;
4902 }
4903 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4904 PyBytes_AS_STRING(val2));
4905#endif
4906 Py_DECREF(key2);
4907 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004908 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004910
4911 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4912 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004913 goto error;
4914 }
Berker Peksag81816462016-09-15 20:19:47 +03004915
Steve Dowercc16be82016-09-08 10:35:16 -07004916 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004917 }
4918 Py_DECREF(vals);
4919 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004920
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 envlist[envc] = 0;
4922 *envc_ptr = envc;
4923 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004924
4925error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 Py_XDECREF(keys);
4927 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004928 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004930}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004931
Steve Dowercc16be82016-09-08 10:35:16 -07004932static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004933parse_arglist(PyObject* argv, Py_ssize_t *argc)
4934{
4935 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004936 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004937 if (argvlist == NULL) {
4938 PyErr_NoMemory();
4939 return NULL;
4940 }
4941 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004942 PyObject* item = PySequence_ITEM(argv, i);
4943 if (item == NULL)
4944 goto fail;
4945 if (!fsconvert_strdup(item, &argvlist[i])) {
4946 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004947 goto fail;
4948 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004949 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004950 }
4951 argvlist[*argc] = NULL;
4952 return argvlist;
4953fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004954 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004955 free_string_array(argvlist, *argc);
4956 return NULL;
4957}
Steve Dowercc16be82016-09-08 10:35:16 -07004958
Ross Lagerwall7807c352011-03-17 20:20:30 +02004959#endif
4960
Larry Hastings2f936352014-08-05 14:04:04 +10004961
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004963/*[clinic input]
4964os.execv
4965
Steve Dowercc16be82016-09-08 10:35:16 -07004966 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004967 Path of executable file.
4968 argv: object
4969 Tuple or list of strings.
4970 /
4971
4972Execute an executable path with arguments, replacing current process.
4973[clinic start generated code]*/
4974
Larry Hastings2f936352014-08-05 14:04:04 +10004975static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004976os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4977/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004978{
Steve Dowercc16be82016-09-08 10:35:16 -07004979 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004980 Py_ssize_t argc;
4981
4982 /* execv has two arguments: (path, argv), where
4983 argv is a list or tuple of strings. */
4984
Ross Lagerwall7807c352011-03-17 20:20:30 +02004985 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4986 PyErr_SetString(PyExc_TypeError,
4987 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004988 return NULL;
4989 }
4990 argc = PySequence_Size(argv);
4991 if (argc < 1) {
4992 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004993 return NULL;
4994 }
4995
4996 argvlist = parse_arglist(argv, &argc);
4997 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004998 return NULL;
4999 }
Steve Dowerbce26262016-11-19 19:17:26 -08005000 if (!argvlist[0][0]) {
5001 PyErr_SetString(PyExc_ValueError,
5002 "execv() arg 2 first element cannot be empty");
5003 free_string_array(argvlist, argc);
5004 return NULL;
5005 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005006
Steve Dowerbce26262016-11-19 19:17:26 -08005007 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005008#ifdef HAVE_WEXECV
5009 _wexecv(path->wide, argvlist);
5010#else
5011 execv(path->narrow, argvlist);
5012#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005013 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014
5015 /* If we get here it's definitely an error */
5016
5017 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 return posix_error();
5019}
5020
Larry Hastings2f936352014-08-05 14:04:04 +10005021
5022/*[clinic input]
5023os.execve
5024
5025 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5026 Path of executable file.
5027 argv: object
5028 Tuple or list of strings.
5029 env: object
5030 Dictionary of strings mapping to strings.
5031
5032Execute an executable path with arguments, replacing current process.
5033[clinic start generated code]*/
5034
Larry Hastings2f936352014-08-05 14:04:04 +10005035static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005036os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5037/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005038{
Steve Dowercc16be82016-09-08 10:35:16 -07005039 EXECV_CHAR **argvlist = NULL;
5040 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005041 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005042
Victor Stinner8c62be82010-05-06 00:08:46 +00005043 /* execve has three arguments: (path, argv, env), where
5044 argv is a list or tuple of strings and env is a dictionary
5045 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005046
Ross Lagerwall7807c352011-03-17 20:20:30 +02005047 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005048 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005049 "execve: argv must be a tuple or list");
5050 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005052 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005053 if (argc < 1) {
5054 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5055 return NULL;
5056 }
5057
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 if (!PyMapping_Check(env)) {
5059 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005060 "execve: environment must be a mapping object");
5061 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005062 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005063
Ross Lagerwall7807c352011-03-17 20:20:30 +02005064 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005065 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005066 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 }
Steve Dowerbce26262016-11-19 19:17:26 -08005068 if (!argvlist[0][0]) {
5069 PyErr_SetString(PyExc_ValueError,
5070 "execve: argv first element cannot be empty");
5071 goto fail;
5072 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005073
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 envlist = parse_envlist(env, &envc);
5075 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 goto fail;
5077
Steve Dowerbce26262016-11-19 19:17:26 -08005078 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005079#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005080 if (path->fd > -1)
5081 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005082 else
5083#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005084#ifdef HAVE_WEXECV
5085 _wexecve(path->wide, argvlist, envlist);
5086#else
Larry Hastings2f936352014-08-05 14:04:04 +10005087 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005088#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005089 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005090
5091 /* If we get here it's definitely an error */
5092
Larry Hastings2f936352014-08-05 14:04:04 +10005093 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005094
Steve Dowercc16be82016-09-08 10:35:16 -07005095 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005096 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005097 if (argvlist)
5098 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005099 return NULL;
5100}
Steve Dowercc16be82016-09-08 10:35:16 -07005101
Larry Hastings9cf065c2012-06-22 16:30:09 -07005102#endif /* HAVE_EXECV */
5103
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005104
Steve Dowercc16be82016-09-08 10:35:16 -07005105#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005106/*[clinic input]
5107os.spawnv
5108
5109 mode: int
5110 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005111 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005112 Path of executable file.
5113 argv: object
5114 Tuple or list of strings.
5115 /
5116
5117Execute the program specified by path in a new process.
5118[clinic start generated code]*/
5119
Larry Hastings2f936352014-08-05 14:04:04 +10005120static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005121os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5122/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005123{
Steve Dowercc16be82016-09-08 10:35:16 -07005124 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005125 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005127 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005129
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 /* spawnv has three arguments: (mode, path, argv), where
5131 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005132
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 if (PyList_Check(argv)) {
5134 argc = PyList_Size(argv);
5135 getitem = PyList_GetItem;
5136 }
5137 else if (PyTuple_Check(argv)) {
5138 argc = PyTuple_Size(argv);
5139 getitem = PyTuple_GetItem;
5140 }
5141 else {
5142 PyErr_SetString(PyExc_TypeError,
5143 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 return NULL;
5145 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005146 if (argc == 0) {
5147 PyErr_SetString(PyExc_ValueError,
5148 "spawnv() arg 2 cannot be empty");
5149 return NULL;
5150 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005151
Steve Dowercc16be82016-09-08 10:35:16 -07005152 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 return PyErr_NoMemory();
5155 }
5156 for (i = 0; i < argc; i++) {
5157 if (!fsconvert_strdup((*getitem)(argv, i),
5158 &argvlist[i])) {
5159 free_string_array(argvlist, i);
5160 PyErr_SetString(
5161 PyExc_TypeError,
5162 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 return NULL;
5164 }
Steve Dower93ff8722016-11-19 19:03:54 -08005165 if (i == 0 && !argvlist[0][0]) {
5166 free_string_array(argvlist, i);
5167 PyErr_SetString(
5168 PyExc_ValueError,
5169 "spawnv() arg 2 first element cannot be empty");
5170 return NULL;
5171 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 }
5173 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005174
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 if (mode == _OLD_P_OVERLAY)
5176 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005177
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005179 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005180#ifdef HAVE_WSPAWNV
5181 spawnval = _wspawnv(mode, path->wide, argvlist);
5182#else
5183 spawnval = _spawnv(mode, path->narrow, argvlist);
5184#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005185 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005187
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005189
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 if (spawnval == -1)
5191 return posix_error();
5192 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005193 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005194}
5195
5196
Larry Hastings2f936352014-08-05 14:04:04 +10005197/*[clinic input]
5198os.spawnve
5199
5200 mode: int
5201 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005202 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005203 Path of executable file.
5204 argv: object
5205 Tuple or list of strings.
5206 env: object
5207 Dictionary of strings mapping to strings.
5208 /
5209
5210Execute the program specified by path in a new process.
5211[clinic start generated code]*/
5212
Larry Hastings2f936352014-08-05 14:04:04 +10005213static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005214os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005215 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005216/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005217{
Steve Dowercc16be82016-09-08 10:35:16 -07005218 EXECV_CHAR **argvlist;
5219 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005220 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005221 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005222 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005223 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5224 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005225
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 /* spawnve has four arguments: (mode, path, argv, env), where
5227 argv is a list or tuple of strings and env is a dictionary
5228 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005229
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 if (PyList_Check(argv)) {
5231 argc = PyList_Size(argv);
5232 getitem = PyList_GetItem;
5233 }
5234 else if (PyTuple_Check(argv)) {
5235 argc = PyTuple_Size(argv);
5236 getitem = PyTuple_GetItem;
5237 }
5238 else {
5239 PyErr_SetString(PyExc_TypeError,
5240 "spawnve() arg 2 must be a tuple or list");
5241 goto fail_0;
5242 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005243 if (argc == 0) {
5244 PyErr_SetString(PyExc_ValueError,
5245 "spawnve() arg 2 cannot be empty");
5246 goto fail_0;
5247 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 if (!PyMapping_Check(env)) {
5249 PyErr_SetString(PyExc_TypeError,
5250 "spawnve() arg 3 must be a mapping object");
5251 goto fail_0;
5252 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005253
Steve Dowercc16be82016-09-08 10:35:16 -07005254 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 if (argvlist == NULL) {
5256 PyErr_NoMemory();
5257 goto fail_0;
5258 }
5259 for (i = 0; i < argc; i++) {
5260 if (!fsconvert_strdup((*getitem)(argv, i),
5261 &argvlist[i]))
5262 {
5263 lastarg = i;
5264 goto fail_1;
5265 }
Steve Dowerbce26262016-11-19 19:17:26 -08005266 if (i == 0 && !argvlist[0][0]) {
5267 lastarg = i;
5268 PyErr_SetString(
5269 PyExc_ValueError,
5270 "spawnv() arg 2 first element cannot be empty");
5271 goto fail_1;
5272 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 }
5274 lastarg = argc;
5275 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005276
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 envlist = parse_envlist(env, &envc);
5278 if (envlist == NULL)
5279 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005280
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 if (mode == _OLD_P_OVERLAY)
5282 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005283
Victor Stinner8c62be82010-05-06 00:08:46 +00005284 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005285 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005286#ifdef HAVE_WSPAWNV
5287 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5288#else
5289 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5290#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005291 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 if (spawnval == -1)
5295 (void) posix_error();
5296 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005297 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 while (--envc >= 0)
5300 PyMem_DEL(envlist[envc]);
5301 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005302 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005304 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005305 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005306}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005307
Guido van Rossuma1065681999-01-25 23:20:23 +00005308#endif /* HAVE_SPAWNV */
5309
5310
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005311#ifdef HAVE_FORK
5312/*[clinic input]
5313os.register_at_fork
5314
5315 func: object
5316 Function or callable
5317 /
5318 when: str
5319 'before', 'child' or 'parent'
5320
5321Register a callable object to be called when forking.
5322
5323'before' callbacks are called in reverse order before forking.
5324'child' callbacks are called in order after forking, in the child process.
5325'parent' callbacks are called in order after forking, in the parent process.
5326
5327[clinic start generated code]*/
5328
5329static PyObject *
5330os_register_at_fork_impl(PyObject *module, PyObject *func, const char *when)
5331/*[clinic end generated code: output=8943be81a644750c input=5fc05efa4d42eb84]*/
5332{
5333 PyInterpreterState *interp;
5334 PyObject **lst;
5335
5336 if (!PyCallable_Check(func)) {
5337 PyErr_Format(PyExc_TypeError,
5338 "expected callable object, got %R", Py_TYPE(func));
5339 return NULL;
5340 }
5341 interp = PyThreadState_Get()->interp;
5342
5343 if (!strcmp(when, "before"))
5344 lst = &interp->before_forkers;
5345 else if (!strcmp(when, "child"))
5346 lst = &interp->after_forkers_child;
5347 else if (!strcmp(when, "parent"))
5348 lst = &interp->after_forkers_parent;
5349 else {
5350 PyErr_Format(PyExc_ValueError, "unexpected value for `when`: '%s'",
5351 when);
5352 return NULL;
5353 }
5354 if (register_at_forker(lst, func))
5355 return NULL;
5356 else
5357 Py_RETURN_NONE;
5358}
5359#endif /* HAVE_FORK */
5360
5361
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005362#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005363/*[clinic input]
5364os.fork1
5365
5366Fork a child process with a single multiplexed (i.e., not bound) thread.
5367
5368Return 0 to child process and PID of child to parent process.
5369[clinic start generated code]*/
5370
Larry Hastings2f936352014-08-05 14:04:04 +10005371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005372os_fork1_impl(PyObject *module)
5373/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005374{
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005376
5377 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 pid = fork1();
5379 if (pid == 0) {
5380 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005381 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 } else {
5383 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005384 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 }
5386 if (pid == -1)
5387 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005388 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005389}
Larry Hastings2f936352014-08-05 14:04:04 +10005390#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005391
5392
Guido van Rossumad0ee831995-03-01 10:34:45 +00005393#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005394/*[clinic input]
5395os.fork
5396
5397Fork a child process.
5398
5399Return 0 to child process and PID of child to parent process.
5400[clinic start generated code]*/
5401
Larry Hastings2f936352014-08-05 14:04:04 +10005402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005403os_fork_impl(PyObject *module)
5404/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005405{
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005407
5408 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005409 pid = fork();
5410 if (pid == 0) {
5411 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005412 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 } else {
5414 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005415 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 }
5417 if (pid == -1)
5418 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005420}
Larry Hastings2f936352014-08-05 14:04:04 +10005421#endif /* HAVE_FORK */
5422
Guido van Rossum85e3b011991-06-03 12:42:10 +00005423
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005424#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005425#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005426/*[clinic input]
5427os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005428
Larry Hastings2f936352014-08-05 14:04:04 +10005429 policy: int
5430
5431Get the maximum scheduling priority for policy.
5432[clinic start generated code]*/
5433
Larry Hastings2f936352014-08-05 14:04:04 +10005434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005435os_sched_get_priority_max_impl(PyObject *module, int policy)
5436/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005437{
5438 int max;
5439
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005440 max = sched_get_priority_max(policy);
5441 if (max < 0)
5442 return posix_error();
5443 return PyLong_FromLong(max);
5444}
5445
Larry Hastings2f936352014-08-05 14:04:04 +10005446
5447/*[clinic input]
5448os.sched_get_priority_min
5449
5450 policy: int
5451
5452Get the minimum scheduling priority for policy.
5453[clinic start generated code]*/
5454
Larry Hastings2f936352014-08-05 14:04:04 +10005455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005456os_sched_get_priority_min_impl(PyObject *module, int policy)
5457/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005458{
5459 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005460 if (min < 0)
5461 return posix_error();
5462 return PyLong_FromLong(min);
5463}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005464#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5465
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005466
Larry Hastings2f936352014-08-05 14:04:04 +10005467#ifdef HAVE_SCHED_SETSCHEDULER
5468/*[clinic input]
5469os.sched_getscheduler
5470 pid: pid_t
5471 /
5472
5473Get the scheduling policy for the process identifiedy by pid.
5474
5475Passing 0 for pid returns the scheduling policy for the calling process.
5476[clinic start generated code]*/
5477
Larry Hastings2f936352014-08-05 14:04:04 +10005478static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005479os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5480/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005481{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005482 int policy;
5483
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005484 policy = sched_getscheduler(pid);
5485 if (policy < 0)
5486 return posix_error();
5487 return PyLong_FromLong(policy);
5488}
Larry Hastings2f936352014-08-05 14:04:04 +10005489#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005490
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005491
5492#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005493/*[clinic input]
5494class os.sched_param "PyObject *" "&SchedParamType"
5495
5496@classmethod
5497os.sched_param.__new__
5498
5499 sched_priority: object
5500 A scheduling parameter.
5501
5502Current has only one field: sched_priority");
5503[clinic start generated code]*/
5504
Larry Hastings2f936352014-08-05 14:04:04 +10005505static PyObject *
5506os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005507/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005508{
5509 PyObject *res;
5510
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005511 res = PyStructSequence_New(type);
5512 if (!res)
5513 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005514 Py_INCREF(sched_priority);
5515 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005516 return res;
5517}
5518
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005519
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005520PyDoc_VAR(os_sched_param__doc__);
5521
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005522static PyStructSequence_Field sched_param_fields[] = {
5523 {"sched_priority", "the scheduling priority"},
5524 {0}
5525};
5526
5527static PyStructSequence_Desc sched_param_desc = {
5528 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005529 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005530 sched_param_fields,
5531 1
5532};
5533
5534static int
5535convert_sched_param(PyObject *param, struct sched_param *res)
5536{
5537 long priority;
5538
5539 if (Py_TYPE(param) != &SchedParamType) {
5540 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5541 return 0;
5542 }
5543 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5544 if (priority == -1 && PyErr_Occurred())
5545 return 0;
5546 if (priority > INT_MAX || priority < INT_MIN) {
5547 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5548 return 0;
5549 }
5550 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5551 return 1;
5552}
Larry Hastings2f936352014-08-05 14:04:04 +10005553#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005554
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005555
5556#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005557/*[clinic input]
5558os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005559
Larry Hastings2f936352014-08-05 14:04:04 +10005560 pid: pid_t
5561 policy: int
5562 param: sched_param
5563 /
5564
5565Set the scheduling policy for the process identified by pid.
5566
5567If pid is 0, the calling process is changed.
5568param is an instance of sched_param.
5569[clinic start generated code]*/
5570
Larry Hastings2f936352014-08-05 14:04:04 +10005571static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005572os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005573 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005574/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005575{
Jesus Cea9c822272011-09-10 01:40:52 +02005576 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005577 ** sched_setscheduler() returns 0 in Linux, but the previous
5578 ** scheduling policy under Solaris/Illumos, and others.
5579 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005580 */
Larry Hastings2f936352014-08-05 14:04:04 +10005581 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005582 return posix_error();
5583 Py_RETURN_NONE;
5584}
Larry Hastings2f936352014-08-05 14:04:04 +10005585#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005587
5588#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005589/*[clinic input]
5590os.sched_getparam
5591 pid: pid_t
5592 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005593
Larry Hastings2f936352014-08-05 14:04:04 +10005594Returns scheduling parameters for the process identified by pid.
5595
5596If pid is 0, returns parameters for the calling process.
5597Return value is an instance of sched_param.
5598[clinic start generated code]*/
5599
Larry Hastings2f936352014-08-05 14:04:04 +10005600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005601os_sched_getparam_impl(PyObject *module, pid_t pid)
5602/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005603{
5604 struct sched_param param;
5605 PyObject *result;
5606 PyObject *priority;
5607
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005608 if (sched_getparam(pid, &param))
5609 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005610 result = PyStructSequence_New(&SchedParamType);
5611 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005612 return NULL;
5613 priority = PyLong_FromLong(param.sched_priority);
5614 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005615 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005616 return NULL;
5617 }
Larry Hastings2f936352014-08-05 14:04:04 +10005618 PyStructSequence_SET_ITEM(result, 0, priority);
5619 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005620}
5621
Larry Hastings2f936352014-08-05 14:04:04 +10005622
5623/*[clinic input]
5624os.sched_setparam
5625 pid: pid_t
5626 param: sched_param
5627 /
5628
5629Set scheduling parameters for the process identified by pid.
5630
5631If pid is 0, sets parameters for the calling process.
5632param should be an instance of sched_param.
5633[clinic start generated code]*/
5634
Larry Hastings2f936352014-08-05 14:04:04 +10005635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005636os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005637 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005638/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005639{
5640 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005641 return posix_error();
5642 Py_RETURN_NONE;
5643}
Larry Hastings2f936352014-08-05 14:04:04 +10005644#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005645
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005646
5647#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005648/*[clinic input]
5649os.sched_rr_get_interval -> double
5650 pid: pid_t
5651 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005652
Larry Hastings2f936352014-08-05 14:04:04 +10005653Return the round-robin quantum for the process identified by pid, in seconds.
5654
5655Value returned is a float.
5656[clinic start generated code]*/
5657
Larry Hastings2f936352014-08-05 14:04:04 +10005658static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005659os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5660/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005661{
5662 struct timespec interval;
5663 if (sched_rr_get_interval(pid, &interval)) {
5664 posix_error();
5665 return -1.0;
5666 }
5667 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5668}
5669#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005670
Larry Hastings2f936352014-08-05 14:04:04 +10005671
5672/*[clinic input]
5673os.sched_yield
5674
5675Voluntarily relinquish the CPU.
5676[clinic start generated code]*/
5677
Larry Hastings2f936352014-08-05 14:04:04 +10005678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005679os_sched_yield_impl(PyObject *module)
5680/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005681{
5682 if (sched_yield())
5683 return posix_error();
5684 Py_RETURN_NONE;
5685}
5686
Benjamin Peterson2740af82011-08-02 17:41:34 -05005687#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005688/* The minimum number of CPUs allocated in a cpu_set_t */
5689static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005690
Larry Hastings2f936352014-08-05 14:04:04 +10005691/*[clinic input]
5692os.sched_setaffinity
5693 pid: pid_t
5694 mask : object
5695 /
5696
5697Set the CPU affinity of the process identified by pid to mask.
5698
5699mask should be an iterable of integers identifying CPUs.
5700[clinic start generated code]*/
5701
Larry Hastings2f936352014-08-05 14:04:04 +10005702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005703os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5704/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005705{
Antoine Pitrou84869872012-08-04 16:16:35 +02005706 int ncpus;
5707 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005708 cpu_set_t *cpu_set = NULL;
5709 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005710
Larry Hastings2f936352014-08-05 14:04:04 +10005711 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005712 if (iterator == NULL)
5713 return NULL;
5714
5715 ncpus = NCPUS_START;
5716 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005717 cpu_set = CPU_ALLOC(ncpus);
5718 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005719 PyErr_NoMemory();
5720 goto error;
5721 }
Larry Hastings2f936352014-08-05 14:04:04 +10005722 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005723
5724 while ((item = PyIter_Next(iterator))) {
5725 long cpu;
5726 if (!PyLong_Check(item)) {
5727 PyErr_Format(PyExc_TypeError,
5728 "expected an iterator of ints, "
5729 "but iterator yielded %R",
5730 Py_TYPE(item));
5731 Py_DECREF(item);
5732 goto error;
5733 }
5734 cpu = PyLong_AsLong(item);
5735 Py_DECREF(item);
5736 if (cpu < 0) {
5737 if (!PyErr_Occurred())
5738 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5739 goto error;
5740 }
5741 if (cpu > INT_MAX - 1) {
5742 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5743 goto error;
5744 }
5745 if (cpu >= ncpus) {
5746 /* Grow CPU mask to fit the CPU number */
5747 int newncpus = ncpus;
5748 cpu_set_t *newmask;
5749 size_t newsetsize;
5750 while (newncpus <= cpu) {
5751 if (newncpus > INT_MAX / 2)
5752 newncpus = cpu + 1;
5753 else
5754 newncpus = newncpus * 2;
5755 }
5756 newmask = CPU_ALLOC(newncpus);
5757 if (newmask == NULL) {
5758 PyErr_NoMemory();
5759 goto error;
5760 }
5761 newsetsize = CPU_ALLOC_SIZE(newncpus);
5762 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005763 memcpy(newmask, cpu_set, setsize);
5764 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005765 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005766 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005767 ncpus = newncpus;
5768 }
Larry Hastings2f936352014-08-05 14:04:04 +10005769 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005770 }
5771 Py_CLEAR(iterator);
5772
Larry Hastings2f936352014-08-05 14:04:04 +10005773 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005774 posix_error();
5775 goto error;
5776 }
Larry Hastings2f936352014-08-05 14:04:04 +10005777 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005778 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005779
5780error:
Larry Hastings2f936352014-08-05 14:04:04 +10005781 if (cpu_set)
5782 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005783 Py_XDECREF(iterator);
5784 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005785}
5786
Larry Hastings2f936352014-08-05 14:04:04 +10005787
5788/*[clinic input]
5789os.sched_getaffinity
5790 pid: pid_t
5791 /
5792
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005793Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005794
5795The affinity is returned as a set of CPU identifiers.
5796[clinic start generated code]*/
5797
Larry Hastings2f936352014-08-05 14:04:04 +10005798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005799os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005800/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005801{
Antoine Pitrou84869872012-08-04 16:16:35 +02005802 int cpu, ncpus, count;
5803 size_t setsize;
5804 cpu_set_t *mask = NULL;
5805 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005806
Antoine Pitrou84869872012-08-04 16:16:35 +02005807 ncpus = NCPUS_START;
5808 while (1) {
5809 setsize = CPU_ALLOC_SIZE(ncpus);
5810 mask = CPU_ALLOC(ncpus);
5811 if (mask == NULL)
5812 return PyErr_NoMemory();
5813 if (sched_getaffinity(pid, setsize, mask) == 0)
5814 break;
5815 CPU_FREE(mask);
5816 if (errno != EINVAL)
5817 return posix_error();
5818 if (ncpus > INT_MAX / 2) {
5819 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5820 "a large enough CPU set");
5821 return NULL;
5822 }
5823 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005824 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005825
5826 res = PySet_New(NULL);
5827 if (res == NULL)
5828 goto error;
5829 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5830 if (CPU_ISSET_S(cpu, setsize, mask)) {
5831 PyObject *cpu_num = PyLong_FromLong(cpu);
5832 --count;
5833 if (cpu_num == NULL)
5834 goto error;
5835 if (PySet_Add(res, cpu_num)) {
5836 Py_DECREF(cpu_num);
5837 goto error;
5838 }
5839 Py_DECREF(cpu_num);
5840 }
5841 }
5842 CPU_FREE(mask);
5843 return res;
5844
5845error:
5846 if (mask)
5847 CPU_FREE(mask);
5848 Py_XDECREF(res);
5849 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005850}
5851
Benjamin Peterson2740af82011-08-02 17:41:34 -05005852#endif /* HAVE_SCHED_SETAFFINITY */
5853
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005854#endif /* HAVE_SCHED_H */
5855
Larry Hastings2f936352014-08-05 14:04:04 +10005856
Neal Norwitzb59798b2003-03-21 01:43:31 +00005857/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005858/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5859#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005860#define DEV_PTY_FILE "/dev/ptc"
5861#define HAVE_DEV_PTMX
5862#else
5863#define DEV_PTY_FILE "/dev/ptmx"
5864#endif
5865
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005866#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005867#ifdef HAVE_PTY_H
5868#include <pty.h>
5869#else
5870#ifdef HAVE_LIBUTIL_H
5871#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005872#else
5873#ifdef HAVE_UTIL_H
5874#include <util.h>
5875#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005876#endif /* HAVE_LIBUTIL_H */
5877#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005878#ifdef HAVE_STROPTS_H
5879#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005880#endif
5881#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005882
Larry Hastings2f936352014-08-05 14:04:04 +10005883
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005884#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005885/*[clinic input]
5886os.openpty
5887
5888Open a pseudo-terminal.
5889
5890Return a tuple of (master_fd, slave_fd) containing open file descriptors
5891for both the master and slave ends.
5892[clinic start generated code]*/
5893
Larry Hastings2f936352014-08-05 14:04:04 +10005894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005895os_openpty_impl(PyObject *module)
5896/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005897{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005898 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005899#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005900 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005901#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005902#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005904#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005906#endif
5907#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005908
Thomas Wouters70c21a12000-07-14 14:28:33 +00005909#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005911 goto posix_error;
5912
5913 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5914 goto error;
5915 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5916 goto error;
5917
Neal Norwitzb59798b2003-03-21 01:43:31 +00005918#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5920 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005921 goto posix_error;
5922 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5923 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005924
Victor Stinnerdaf45552013-08-28 00:53:59 +02005925 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005927 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005928
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005929#else
Victor Stinner000de532013-11-25 23:19:58 +01005930 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005932 goto posix_error;
5933
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005935
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 /* change permission of slave */
5937 if (grantpt(master_fd) < 0) {
5938 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005939 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005941
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 /* unlock slave */
5943 if (unlockpt(master_fd) < 0) {
5944 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005945 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005947
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005949
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 slave_name = ptsname(master_fd); /* get name of slave */
5951 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005952 goto posix_error;
5953
5954 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005955 if (slave_fd == -1)
5956 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005957
5958 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5959 goto posix_error;
5960
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005961#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5963 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005964#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005966#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005967#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005968#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005969
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005971
Victor Stinnerdaf45552013-08-28 00:53:59 +02005972posix_error:
5973 posix_error();
5974error:
5975 if (master_fd != -1)
5976 close(master_fd);
5977 if (slave_fd != -1)
5978 close(slave_fd);
5979 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005980}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005981#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005982
Larry Hastings2f936352014-08-05 14:04:04 +10005983
Fred Drake8cef4cf2000-06-28 16:40:38 +00005984#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005985/*[clinic input]
5986os.forkpty
5987
5988Fork a new process with a new pseudo-terminal as controlling tty.
5989
5990Returns a tuple of (pid, master_fd).
5991Like fork(), return pid of 0 to the child process,
5992and pid of child to the parent process.
5993To both, return fd of newly opened pseudo-terminal.
5994[clinic start generated code]*/
5995
Larry Hastings2f936352014-08-05 14:04:04 +10005996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005997os_forkpty_impl(PyObject *module)
5998/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005999{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006000 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006002
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006003 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 pid = forkpty(&master_fd, NULL, NULL, NULL);
6005 if (pid == 0) {
6006 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006007 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 } else {
6009 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006010 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 }
6012 if (pid == -1)
6013 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006015}
Larry Hastings2f936352014-08-05 14:04:04 +10006016#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006017
Ross Lagerwall7807c352011-03-17 20:20:30 +02006018
Guido van Rossumad0ee831995-03-01 10:34:45 +00006019#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006020/*[clinic input]
6021os.getegid
6022
6023Return the current process's effective group id.
6024[clinic start generated code]*/
6025
Larry Hastings2f936352014-08-05 14:04:04 +10006026static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006027os_getegid_impl(PyObject *module)
6028/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006029{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006030 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006031}
Larry Hastings2f936352014-08-05 14:04:04 +10006032#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006034
Guido van Rossumad0ee831995-03-01 10:34:45 +00006035#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006036/*[clinic input]
6037os.geteuid
6038
6039Return the current process's effective user id.
6040[clinic start generated code]*/
6041
Larry Hastings2f936352014-08-05 14:04:04 +10006042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006043os_geteuid_impl(PyObject *module)
6044/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006045{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006046 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006047}
Larry Hastings2f936352014-08-05 14:04:04 +10006048#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006050
Guido van Rossumad0ee831995-03-01 10:34:45 +00006051#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006052/*[clinic input]
6053os.getgid
6054
6055Return the current process's group id.
6056[clinic start generated code]*/
6057
Larry Hastings2f936352014-08-05 14:04:04 +10006058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006059os_getgid_impl(PyObject *module)
6060/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006061{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006062 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006063}
Larry Hastings2f936352014-08-05 14:04:04 +10006064#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006066
Berker Peksag39404992016-09-15 20:45:16 +03006067#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006068/*[clinic input]
6069os.getpid
6070
6071Return the current process id.
6072[clinic start generated code]*/
6073
Larry Hastings2f936352014-08-05 14:04:04 +10006074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006075os_getpid_impl(PyObject *module)
6076/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006077{
Victor Stinner8c62be82010-05-06 00:08:46 +00006078 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006079}
Berker Peksag39404992016-09-15 20:45:16 +03006080#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006081
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006082#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006083
6084/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006085PyDoc_STRVAR(posix_getgrouplist__doc__,
6086"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6087Returns a list of groups to which a user belongs.\n\n\
6088 user: username to lookup\n\
6089 group: base group id of the user");
6090
6091static PyObject *
6092posix_getgrouplist(PyObject *self, PyObject *args)
6093{
6094#ifdef NGROUPS_MAX
6095#define MAX_GROUPS NGROUPS_MAX
6096#else
6097 /* defined to be 16 on Solaris7, so this should be a small number */
6098#define MAX_GROUPS 64
6099#endif
6100
6101 const char *user;
6102 int i, ngroups;
6103 PyObject *list;
6104#ifdef __APPLE__
6105 int *groups, basegid;
6106#else
6107 gid_t *groups, basegid;
6108#endif
6109 ngroups = MAX_GROUPS;
6110
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006111#ifdef __APPLE__
6112 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006113 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006114#else
6115 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6116 _Py_Gid_Converter, &basegid))
6117 return NULL;
6118#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006119
6120#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006121 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006122#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006123 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006124#endif
6125 if (groups == NULL)
6126 return PyErr_NoMemory();
6127
6128 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6129 PyMem_Del(groups);
6130 return posix_error();
6131 }
6132
6133 list = PyList_New(ngroups);
6134 if (list == NULL) {
6135 PyMem_Del(groups);
6136 return NULL;
6137 }
6138
6139 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006140#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006141 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006142#else
6143 PyObject *o = _PyLong_FromGid(groups[i]);
6144#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006145 if (o == NULL) {
6146 Py_DECREF(list);
6147 PyMem_Del(groups);
6148 return NULL;
6149 }
6150 PyList_SET_ITEM(list, i, o);
6151 }
6152
6153 PyMem_Del(groups);
6154
6155 return list;
6156}
Larry Hastings2f936352014-08-05 14:04:04 +10006157#endif /* HAVE_GETGROUPLIST */
6158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006159
Fred Drakec9680921999-12-13 16:37:25 +00006160#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006161/*[clinic input]
6162os.getgroups
6163
6164Return list of supplemental group IDs for the process.
6165[clinic start generated code]*/
6166
Larry Hastings2f936352014-08-05 14:04:04 +10006167static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006168os_getgroups_impl(PyObject *module)
6169/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006170{
6171 PyObject *result = NULL;
6172
Fred Drakec9680921999-12-13 16:37:25 +00006173#ifdef NGROUPS_MAX
6174#define MAX_GROUPS NGROUPS_MAX
6175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006177#define MAX_GROUPS 64
6178#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006179 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006180
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006181 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006182 * This is a helper variable to store the intermediate result when
6183 * that happens.
6184 *
6185 * To keep the code readable the OSX behaviour is unconditional,
6186 * according to the POSIX spec this should be safe on all unix-y
6187 * systems.
6188 */
6189 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006190 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006191
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006192#ifdef __APPLE__
6193 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6194 * there are more groups than can fit in grouplist. Therefore, on OS X
6195 * always first call getgroups with length 0 to get the actual number
6196 * of groups.
6197 */
6198 n = getgroups(0, NULL);
6199 if (n < 0) {
6200 return posix_error();
6201 } else if (n <= MAX_GROUPS) {
6202 /* groups will fit in existing array */
6203 alt_grouplist = grouplist;
6204 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006205 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006206 if (alt_grouplist == NULL) {
6207 errno = EINVAL;
6208 return posix_error();
6209 }
6210 }
6211
6212 n = getgroups(n, alt_grouplist);
6213 if (n == -1) {
6214 if (alt_grouplist != grouplist) {
6215 PyMem_Free(alt_grouplist);
6216 }
6217 return posix_error();
6218 }
6219#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006221 if (n < 0) {
6222 if (errno == EINVAL) {
6223 n = getgroups(0, NULL);
6224 if (n == -1) {
6225 return posix_error();
6226 }
6227 if (n == 0) {
6228 /* Avoid malloc(0) */
6229 alt_grouplist = grouplist;
6230 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006231 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006232 if (alt_grouplist == NULL) {
6233 errno = EINVAL;
6234 return posix_error();
6235 }
6236 n = getgroups(n, alt_grouplist);
6237 if (n == -1) {
6238 PyMem_Free(alt_grouplist);
6239 return posix_error();
6240 }
6241 }
6242 } else {
6243 return posix_error();
6244 }
6245 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006246#endif
6247
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006248 result = PyList_New(n);
6249 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 int i;
6251 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006252 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006253 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006254 Py_DECREF(result);
6255 result = NULL;
6256 break;
Fred Drakec9680921999-12-13 16:37:25 +00006257 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006259 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006260 }
6261
6262 if (alt_grouplist != grouplist) {
6263 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006265
Fred Drakec9680921999-12-13 16:37:25 +00006266 return result;
6267}
Larry Hastings2f936352014-08-05 14:04:04 +10006268#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006269
Antoine Pitroub7572f02009-12-02 20:46:48 +00006270#ifdef HAVE_INITGROUPS
6271PyDoc_STRVAR(posix_initgroups__doc__,
6272"initgroups(username, gid) -> None\n\n\
6273Call the system initgroups() to initialize the group access list with all of\n\
6274the groups of which the specified username is a member, plus the specified\n\
6275group id.");
6276
Larry Hastings2f936352014-08-05 14:04:04 +10006277/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006278static PyObject *
6279posix_initgroups(PyObject *self, PyObject *args)
6280{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006281 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006282 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006283 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006284#ifdef __APPLE__
6285 int gid;
6286#else
6287 gid_t gid;
6288#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006289
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006290#ifdef __APPLE__
6291 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6292 PyUnicode_FSConverter, &oname,
6293 &gid))
6294#else
6295 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6296 PyUnicode_FSConverter, &oname,
6297 _Py_Gid_Converter, &gid))
6298#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006300 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006301
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006302 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006303 Py_DECREF(oname);
6304 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006306
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006307 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006308}
Larry Hastings2f936352014-08-05 14:04:04 +10006309#endif /* HAVE_INITGROUPS */
6310
Antoine Pitroub7572f02009-12-02 20:46:48 +00006311
Martin v. Löwis606edc12002-06-13 21:09:11 +00006312#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006313/*[clinic input]
6314os.getpgid
6315
6316 pid: pid_t
6317
6318Call the system call getpgid(), and return the result.
6319[clinic start generated code]*/
6320
Larry Hastings2f936352014-08-05 14:04:04 +10006321static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006322os_getpgid_impl(PyObject *module, pid_t pid)
6323/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006324{
6325 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 if (pgid < 0)
6327 return posix_error();
6328 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006329}
6330#endif /* HAVE_GETPGID */
6331
6332
Guido van Rossumb6775db1994-08-01 11:34:53 +00006333#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006334/*[clinic input]
6335os.getpgrp
6336
6337Return the current process group id.
6338[clinic start generated code]*/
6339
Larry Hastings2f936352014-08-05 14:04:04 +10006340static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006341os_getpgrp_impl(PyObject *module)
6342/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006343{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006344#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006346#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006347 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006348#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006349}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006350#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006352
Guido van Rossumb6775db1994-08-01 11:34:53 +00006353#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006354/*[clinic input]
6355os.setpgrp
6356
6357Make the current process the leader of its process group.
6358[clinic start generated code]*/
6359
Larry Hastings2f936352014-08-05 14:04:04 +10006360static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006361os_setpgrp_impl(PyObject *module)
6362/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006363{
Guido van Rossum64933891994-10-20 21:56:42 +00006364#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006366#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006368#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006370 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006371}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006372#endif /* HAVE_SETPGRP */
6373
Guido van Rossumad0ee831995-03-01 10:34:45 +00006374#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006375
6376#ifdef MS_WINDOWS
6377#include <tlhelp32.h>
6378
6379static PyObject*
6380win32_getppid()
6381{
6382 HANDLE snapshot;
6383 pid_t mypid;
6384 PyObject* result = NULL;
6385 BOOL have_record;
6386 PROCESSENTRY32 pe;
6387
6388 mypid = getpid(); /* This function never fails */
6389
6390 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6391 if (snapshot == INVALID_HANDLE_VALUE)
6392 return PyErr_SetFromWindowsErr(GetLastError());
6393
6394 pe.dwSize = sizeof(pe);
6395 have_record = Process32First(snapshot, &pe);
6396 while (have_record) {
6397 if (mypid == (pid_t)pe.th32ProcessID) {
6398 /* We could cache the ulong value in a static variable. */
6399 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6400 break;
6401 }
6402
6403 have_record = Process32Next(snapshot, &pe);
6404 }
6405
6406 /* If our loop exits and our pid was not found (result will be NULL)
6407 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6408 * error anyway, so let's raise it. */
6409 if (!result)
6410 result = PyErr_SetFromWindowsErr(GetLastError());
6411
6412 CloseHandle(snapshot);
6413
6414 return result;
6415}
6416#endif /*MS_WINDOWS*/
6417
Larry Hastings2f936352014-08-05 14:04:04 +10006418
6419/*[clinic input]
6420os.getppid
6421
6422Return the parent's process id.
6423
6424If the parent process has already exited, Windows machines will still
6425return its id; others systems will return the id of the 'init' process (1).
6426[clinic start generated code]*/
6427
Larry Hastings2f936352014-08-05 14:04:04 +10006428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006429os_getppid_impl(PyObject *module)
6430/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006431{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006432#ifdef MS_WINDOWS
6433 return win32_getppid();
6434#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006436#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006437}
6438#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006440
Fred Drake12c6e2d1999-12-14 21:25:03 +00006441#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006442/*[clinic input]
6443os.getlogin
6444
6445Return the actual login name.
6446[clinic start generated code]*/
6447
Larry Hastings2f936352014-08-05 14:04:04 +10006448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006449os_getlogin_impl(PyObject *module)
6450/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006451{
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006453#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006454 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006455 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006456
6457 if (GetUserNameW(user_name, &num_chars)) {
6458 /* num_chars is the number of unicode chars plus null terminator */
6459 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006460 }
6461 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006462 result = PyErr_SetFromWindowsErr(GetLastError());
6463#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006464 char *name;
6465 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006466
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 errno = 0;
6468 name = getlogin();
6469 if (name == NULL) {
6470 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006471 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006472 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006473 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006474 }
6475 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006476 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006478#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006479 return result;
6480}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006481#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006482
Larry Hastings2f936352014-08-05 14:04:04 +10006483
Guido van Rossumad0ee831995-03-01 10:34:45 +00006484#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006485/*[clinic input]
6486os.getuid
6487
6488Return the current process's user id.
6489[clinic start generated code]*/
6490
Larry Hastings2f936352014-08-05 14:04:04 +10006491static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006492os_getuid_impl(PyObject *module)
6493/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006494{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006495 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006496}
Larry Hastings2f936352014-08-05 14:04:04 +10006497#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006499
Brian Curtineb24d742010-04-12 17:16:38 +00006500#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006501#define HAVE_KILL
6502#endif /* MS_WINDOWS */
6503
6504#ifdef HAVE_KILL
6505/*[clinic input]
6506os.kill
6507
6508 pid: pid_t
6509 signal: Py_ssize_t
6510 /
6511
6512Kill a process with a signal.
6513[clinic start generated code]*/
6514
Larry Hastings2f936352014-08-05 14:04:04 +10006515static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006516os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6517/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006518#ifndef MS_WINDOWS
6519{
6520 if (kill(pid, (int)signal) == -1)
6521 return posix_error();
6522 Py_RETURN_NONE;
6523}
6524#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006525{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006526 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006527 DWORD sig = (DWORD)signal;
6528 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006530
Victor Stinner8c62be82010-05-06 00:08:46 +00006531 /* Console processes which share a common console can be sent CTRL+C or
6532 CTRL+BREAK events, provided they handle said events. */
6533 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006534 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 err = GetLastError();
6536 PyErr_SetFromWindowsErr(err);
6537 }
6538 else
6539 Py_RETURN_NONE;
6540 }
Brian Curtineb24d742010-04-12 17:16:38 +00006541
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6543 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006544 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 if (handle == NULL) {
6546 err = GetLastError();
6547 return PyErr_SetFromWindowsErr(err);
6548 }
Brian Curtineb24d742010-04-12 17:16:38 +00006549
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 if (TerminateProcess(handle, sig) == 0) {
6551 err = GetLastError();
6552 result = PyErr_SetFromWindowsErr(err);
6553 } else {
6554 Py_INCREF(Py_None);
6555 result = Py_None;
6556 }
Brian Curtineb24d742010-04-12 17:16:38 +00006557
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 CloseHandle(handle);
6559 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006560}
Larry Hastings2f936352014-08-05 14:04:04 +10006561#endif /* !MS_WINDOWS */
6562#endif /* HAVE_KILL */
6563
6564
6565#ifdef HAVE_KILLPG
6566/*[clinic input]
6567os.killpg
6568
6569 pgid: pid_t
6570 signal: int
6571 /
6572
6573Kill a process group with a signal.
6574[clinic start generated code]*/
6575
Larry Hastings2f936352014-08-05 14:04:04 +10006576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006577os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6578/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006579{
6580 /* XXX some man pages make the `pgid` parameter an int, others
6581 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6582 take the same type. Moreover, pid_t is always at least as wide as
6583 int (else compilation of this module fails), which is safe. */
6584 if (killpg(pgid, signal) == -1)
6585 return posix_error();
6586 Py_RETURN_NONE;
6587}
6588#endif /* HAVE_KILLPG */
6589
Brian Curtineb24d742010-04-12 17:16:38 +00006590
Guido van Rossumc0125471996-06-28 18:55:32 +00006591#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006592#ifdef HAVE_SYS_LOCK_H
6593#include <sys/lock.h>
6594#endif
6595
Larry Hastings2f936352014-08-05 14:04:04 +10006596/*[clinic input]
6597os.plock
6598 op: int
6599 /
6600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006601Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006602[clinic start generated code]*/
6603
Larry Hastings2f936352014-08-05 14:04:04 +10006604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006605os_plock_impl(PyObject *module, int op)
6606/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006607{
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 if (plock(op) == -1)
6609 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006610 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006611}
Larry Hastings2f936352014-08-05 14:04:04 +10006612#endif /* HAVE_PLOCK */
6613
Guido van Rossumc0125471996-06-28 18:55:32 +00006614
Guido van Rossumb6775db1994-08-01 11:34:53 +00006615#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006616/*[clinic input]
6617os.setuid
6618
6619 uid: uid_t
6620 /
6621
6622Set the current process's user id.
6623[clinic start generated code]*/
6624
Larry Hastings2f936352014-08-05 14:04:04 +10006625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006626os_setuid_impl(PyObject *module, uid_t uid)
6627/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006628{
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 if (setuid(uid) < 0)
6630 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006631 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006632}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006633#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006634
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006635
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006636#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006637/*[clinic input]
6638os.seteuid
6639
6640 euid: uid_t
6641 /
6642
6643Set the current process's effective user id.
6644[clinic start generated code]*/
6645
Larry Hastings2f936352014-08-05 14:04:04 +10006646static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006647os_seteuid_impl(PyObject *module, uid_t euid)
6648/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006649{
6650 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006652 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006653}
6654#endif /* HAVE_SETEUID */
6655
Larry Hastings2f936352014-08-05 14:04:04 +10006656
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006657#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006658/*[clinic input]
6659os.setegid
6660
6661 egid: gid_t
6662 /
6663
6664Set the current process's effective group id.
6665[clinic start generated code]*/
6666
Larry Hastings2f936352014-08-05 14:04:04 +10006667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006668os_setegid_impl(PyObject *module, gid_t egid)
6669/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006670{
6671 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006672 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006673 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006674}
6675#endif /* HAVE_SETEGID */
6676
Larry Hastings2f936352014-08-05 14:04:04 +10006677
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006678#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006679/*[clinic input]
6680os.setreuid
6681
6682 ruid: uid_t
6683 euid: uid_t
6684 /
6685
6686Set the current process's real and effective user ids.
6687[clinic start generated code]*/
6688
Larry Hastings2f936352014-08-05 14:04:04 +10006689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006690os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6691/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006692{
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 if (setreuid(ruid, euid) < 0) {
6694 return posix_error();
6695 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006696 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006698}
6699#endif /* HAVE_SETREUID */
6700
Larry Hastings2f936352014-08-05 14:04:04 +10006701
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006702#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006703/*[clinic input]
6704os.setregid
6705
6706 rgid: gid_t
6707 egid: gid_t
6708 /
6709
6710Set the current process's real and effective group ids.
6711[clinic start generated code]*/
6712
Larry Hastings2f936352014-08-05 14:04:04 +10006713static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006714os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6715/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006716{
6717 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006719 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006720}
6721#endif /* HAVE_SETREGID */
6722
Larry Hastings2f936352014-08-05 14:04:04 +10006723
Guido van Rossumb6775db1994-08-01 11:34:53 +00006724#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006725/*[clinic input]
6726os.setgid
6727 gid: gid_t
6728 /
6729
6730Set the current process's group id.
6731[clinic start generated code]*/
6732
Larry Hastings2f936352014-08-05 14:04:04 +10006733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006734os_setgid_impl(PyObject *module, gid_t gid)
6735/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006736{
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 if (setgid(gid) < 0)
6738 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006739 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006740}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006741#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006742
Larry Hastings2f936352014-08-05 14:04:04 +10006743
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006744#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006745/*[clinic input]
6746os.setgroups
6747
6748 groups: object
6749 /
6750
6751Set the groups of the current process to list.
6752[clinic start generated code]*/
6753
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006755os_setgroups(PyObject *module, PyObject *groups)
6756/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006757{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006758 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006760
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (!PySequence_Check(groups)) {
6762 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6763 return NULL;
6764 }
6765 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006766 if (len < 0) {
6767 return NULL;
6768 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 if (len > MAX_GROUPS) {
6770 PyErr_SetString(PyExc_ValueError, "too many groups");
6771 return NULL;
6772 }
6773 for(i = 0; i < len; i++) {
6774 PyObject *elem;
6775 elem = PySequence_GetItem(groups, i);
6776 if (!elem)
6777 return NULL;
6778 if (!PyLong_Check(elem)) {
6779 PyErr_SetString(PyExc_TypeError,
6780 "groups must be integers");
6781 Py_DECREF(elem);
6782 return NULL;
6783 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006784 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 Py_DECREF(elem);
6786 return NULL;
6787 }
6788 }
6789 Py_DECREF(elem);
6790 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006791
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 if (setgroups(len, grouplist) < 0)
6793 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006794 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006795}
6796#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006797
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006798#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6799static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006800wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006801{
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 PyObject *result;
6803 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006804 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006805
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 if (pid == -1)
6807 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006808
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 if (struct_rusage == NULL) {
6810 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6811 if (m == NULL)
6812 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006813 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 Py_DECREF(m);
6815 if (struct_rusage == NULL)
6816 return NULL;
6817 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6820 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6821 if (!result)
6822 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006823
6824#ifndef doubletime
6825#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6826#endif
6827
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006829 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006831 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6834 SET_INT(result, 2, ru->ru_maxrss);
6835 SET_INT(result, 3, ru->ru_ixrss);
6836 SET_INT(result, 4, ru->ru_idrss);
6837 SET_INT(result, 5, ru->ru_isrss);
6838 SET_INT(result, 6, ru->ru_minflt);
6839 SET_INT(result, 7, ru->ru_majflt);
6840 SET_INT(result, 8, ru->ru_nswap);
6841 SET_INT(result, 9, ru->ru_inblock);
6842 SET_INT(result, 10, ru->ru_oublock);
6843 SET_INT(result, 11, ru->ru_msgsnd);
6844 SET_INT(result, 12, ru->ru_msgrcv);
6845 SET_INT(result, 13, ru->ru_nsignals);
6846 SET_INT(result, 14, ru->ru_nvcsw);
6847 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006848#undef SET_INT
6849
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 if (PyErr_Occurred()) {
6851 Py_DECREF(result);
6852 return NULL;
6853 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006854
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006856}
6857#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6858
Larry Hastings2f936352014-08-05 14:04:04 +10006859
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006860#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006861/*[clinic input]
6862os.wait3
6863
6864 options: int
6865Wait for completion of a child process.
6866
6867Returns a tuple of information about the child process:
6868 (pid, status, rusage)
6869[clinic start generated code]*/
6870
Larry Hastings2f936352014-08-05 14:04:04 +10006871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006872os_wait3_impl(PyObject *module, int options)
6873/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874{
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006876 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006877 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 WAIT_TYPE status;
6879 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006881 do {
6882 Py_BEGIN_ALLOW_THREADS
6883 pid = wait3(&status, options, &ru);
6884 Py_END_ALLOW_THREADS
6885 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6886 if (pid < 0)
6887 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888
Victor Stinner4195b5c2012-02-08 23:03:19 +01006889 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006890}
6891#endif /* HAVE_WAIT3 */
6892
Larry Hastings2f936352014-08-05 14:04:04 +10006893
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006895/*[clinic input]
6896
6897os.wait4
6898
6899 pid: pid_t
6900 options: int
6901
6902Wait for completion of a specific child process.
6903
6904Returns a tuple of information about the child process:
6905 (pid, status, rusage)
6906[clinic start generated code]*/
6907
Larry Hastings2f936352014-08-05 14:04:04 +10006908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006909os_wait4_impl(PyObject *module, pid_t pid, int options)
6910/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006911{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006912 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006914 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006915 WAIT_TYPE status;
6916 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006918 do {
6919 Py_BEGIN_ALLOW_THREADS
6920 res = wait4(pid, &status, options, &ru);
6921 Py_END_ALLOW_THREADS
6922 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6923 if (res < 0)
6924 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006926 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006927}
6928#endif /* HAVE_WAIT4 */
6929
Larry Hastings2f936352014-08-05 14:04:04 +10006930
Ross Lagerwall7807c352011-03-17 20:20:30 +02006931#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006932/*[clinic input]
6933os.waitid
6934
6935 idtype: idtype_t
6936 Must be one of be P_PID, P_PGID or P_ALL.
6937 id: id_t
6938 The id to wait on.
6939 options: int
6940 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6941 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6942 /
6943
6944Returns the result of waiting for a process or processes.
6945
6946Returns either waitid_result or None if WNOHANG is specified and there are
6947no children in a waitable state.
6948[clinic start generated code]*/
6949
Larry Hastings2f936352014-08-05 14:04:04 +10006950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006951os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6952/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006953{
6954 PyObject *result;
6955 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006956 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006957 siginfo_t si;
6958 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006959
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006960 do {
6961 Py_BEGIN_ALLOW_THREADS
6962 res = waitid(idtype, id, &si, options);
6963 Py_END_ALLOW_THREADS
6964 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6965 if (res < 0)
6966 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006967
6968 if (si.si_pid == 0)
6969 Py_RETURN_NONE;
6970
6971 result = PyStructSequence_New(&WaitidResultType);
6972 if (!result)
6973 return NULL;
6974
6975 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006976 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006977 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6978 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6979 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6980 if (PyErr_Occurred()) {
6981 Py_DECREF(result);
6982 return NULL;
6983 }
6984
6985 return result;
6986}
Larry Hastings2f936352014-08-05 14:04:04 +10006987#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006988
Larry Hastings2f936352014-08-05 14:04:04 +10006989
6990#if defined(HAVE_WAITPID)
6991/*[clinic input]
6992os.waitpid
6993 pid: pid_t
6994 options: int
6995 /
6996
6997Wait for completion of a given child process.
6998
6999Returns a tuple of information regarding the child process:
7000 (pid, status)
7001
7002The options argument is ignored on Windows.
7003[clinic start generated code]*/
7004
Larry Hastings2f936352014-08-05 14:04:04 +10007005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007006os_waitpid_impl(PyObject *module, pid_t pid, int options)
7007/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007008{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007009 pid_t res;
7010 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 WAIT_TYPE status;
7012 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007013
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007014 do {
7015 Py_BEGIN_ALLOW_THREADS
7016 res = waitpid(pid, &status, options);
7017 Py_END_ALLOW_THREADS
7018 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7019 if (res < 0)
7020 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007021
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007022 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007023}
Tim Petersab034fa2002-02-01 11:27:43 +00007024#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007025/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007026/*[clinic input]
7027os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007028 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007029 options: int
7030 /
7031
7032Wait for completion of a given process.
7033
7034Returns a tuple of information regarding the process:
7035 (pid, status << 8)
7036
7037The options argument is ignored on Windows.
7038[clinic start generated code]*/
7039
Larry Hastings2f936352014-08-05 14:04:04 +10007040static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007041os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007042/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007043{
7044 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007045 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007046 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007047
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007048 do {
7049 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007050 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007051 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007052 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007053 Py_END_ALLOW_THREADS
7054 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007055 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007056 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007057
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007059 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007060}
Larry Hastings2f936352014-08-05 14:04:04 +10007061#endif
7062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007063
Guido van Rossumad0ee831995-03-01 10:34:45 +00007064#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007065/*[clinic input]
7066os.wait
7067
7068Wait for completion of a child process.
7069
7070Returns a tuple of information about the child process:
7071 (pid, status)
7072[clinic start generated code]*/
7073
Larry Hastings2f936352014-08-05 14:04:04 +10007074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007075os_wait_impl(PyObject *module)
7076/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007077{
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007079 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007080 WAIT_TYPE status;
7081 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007082
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007083 do {
7084 Py_BEGIN_ALLOW_THREADS
7085 pid = wait(&status);
7086 Py_END_ALLOW_THREADS
7087 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7088 if (pid < 0)
7089 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007090
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007092}
Larry Hastings2f936352014-08-05 14:04:04 +10007093#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007095
Larry Hastings9cf065c2012-06-22 16:30:09 -07007096#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7097PyDoc_STRVAR(readlink__doc__,
7098"readlink(path, *, dir_fd=None) -> path\n\n\
7099Return a string representing the path to which the symbolic link points.\n\
7100\n\
7101If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7102 and path should be relative; path will then be relative to that directory.\n\
7103dir_fd may not be implemented on your platform.\n\
7104 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007105#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007106
Guido van Rossumb6775db1994-08-01 11:34:53 +00007107#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007108
Larry Hastings2f936352014-08-05 14:04:04 +10007109/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007110static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007112{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113 path_t path;
7114 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007115 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116 ssize_t length;
7117 PyObject *return_value = NULL;
7118 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007119
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007121 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7123 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007124 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007125 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007126
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128#ifdef HAVE_READLINKAT
7129 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007130 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007131 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007132#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007133 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134 Py_END_ALLOW_THREADS
7135
7136 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007137 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138 goto exit;
7139 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007140 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007141
7142 if (PyUnicode_Check(path.object))
7143 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7144 else
7145 return_value = PyBytes_FromStringAndSize(buffer, length);
7146exit:
7147 path_cleanup(&path);
7148 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007149}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007150
Guido van Rossumb6775db1994-08-01 11:34:53 +00007151#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007152
Larry Hastings2f936352014-08-05 14:04:04 +10007153#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7154
7155static PyObject *
7156win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7157{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007158 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007159 DWORD n_bytes_returned;
7160 DWORD io_result;
7161 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007162 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007163 HANDLE reparse_point_handle;
7164
Martin Panter70214ad2016-08-04 02:38:59 +00007165 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7166 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007167 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007168
7169 static char *keywords[] = {"path", "dir_fd", NULL};
7170
7171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7172 &po,
7173 dir_fd_unavailable, &dir_fd
7174 ))
7175 return NULL;
7176
7177 path = PyUnicode_AsUnicode(po);
7178 if (path == NULL)
7179 return NULL;
7180
7181 /* First get a handle to the reparse point */
7182 Py_BEGIN_ALLOW_THREADS
7183 reparse_point_handle = CreateFileW(
7184 path,
7185 0,
7186 0,
7187 0,
7188 OPEN_EXISTING,
7189 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7190 0);
7191 Py_END_ALLOW_THREADS
7192
7193 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7194 return win32_error_object("readlink", po);
7195
7196 Py_BEGIN_ALLOW_THREADS
7197 /* New call DeviceIoControl to read the reparse point */
7198 io_result = DeviceIoControl(
7199 reparse_point_handle,
7200 FSCTL_GET_REPARSE_POINT,
7201 0, 0, /* in buffer */
7202 target_buffer, sizeof(target_buffer),
7203 &n_bytes_returned,
7204 0 /* we're not using OVERLAPPED_IO */
7205 );
7206 CloseHandle(reparse_point_handle);
7207 Py_END_ALLOW_THREADS
7208
7209 if (io_result==0)
7210 return win32_error_object("readlink", po);
7211
7212 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7213 {
7214 PyErr_SetString(PyExc_ValueError,
7215 "not a symbolic link");
7216 return NULL;
7217 }
7218 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7219 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7220
7221 result = PyUnicode_FromWideChar(print_name,
7222 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7223 return result;
7224}
7225
7226#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7227
7228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007229
Larry Hastings9cf065c2012-06-22 16:30:09 -07007230#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007231
7232#if defined(MS_WINDOWS)
7233
7234/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007235static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007236
Larry Hastings9cf065c2012-06-22 16:30:09 -07007237static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007238check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007239{
7240 HINSTANCE hKernel32;
7241 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007242 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007243 return 1;
7244 hKernel32 = GetModuleHandleW(L"KERNEL32");
7245 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7246 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007247 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007248}
7249
Victor Stinner31b3b922013-06-05 01:49:17 +02007250/* Remove the last portion of the path */
7251static void
7252_dirnameW(WCHAR *path)
7253{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254 WCHAR *ptr;
7255
7256 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007257 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007258 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007259 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007260 }
7261 *ptr = 0;
7262}
7263
Victor Stinner31b3b922013-06-05 01:49:17 +02007264/* Is this path absolute? */
7265static int
7266_is_absW(const WCHAR *path)
7267{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007268 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7269
7270}
7271
Victor Stinner31b3b922013-06-05 01:49:17 +02007272/* join root and rest with a backslash */
7273static void
7274_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7275{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007276 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277
Victor Stinner31b3b922013-06-05 01:49:17 +02007278 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007279 wcscpy(dest_path, rest);
7280 return;
7281 }
7282
7283 root_len = wcslen(root);
7284
7285 wcscpy(dest_path, root);
7286 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007287 dest_path[root_len] = L'\\';
7288 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289 }
7290 wcscpy(dest_path+root_len, rest);
7291}
7292
Victor Stinner31b3b922013-06-05 01:49:17 +02007293/* Return True if the path at src relative to dest is a directory */
7294static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007295_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007296{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297 WIN32_FILE_ATTRIBUTE_DATA src_info;
7298 WCHAR dest_parent[MAX_PATH];
7299 WCHAR src_resolved[MAX_PATH] = L"";
7300
7301 /* dest_parent = os.path.dirname(dest) */
7302 wcscpy(dest_parent, dest);
7303 _dirnameW(dest_parent);
7304 /* src_resolved = os.path.join(dest_parent, src) */
7305 _joinW(src_resolved, dest_parent, src);
7306 return (
7307 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7308 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7309 );
7310}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007311#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007312
Larry Hastings2f936352014-08-05 14:04:04 +10007313
7314/*[clinic input]
7315os.symlink
7316 src: path_t
7317 dst: path_t
7318 target_is_directory: bool = False
7319 *
7320 dir_fd: dir_fd(requires='symlinkat')=None
7321
7322# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7323
7324Create a symbolic link pointing to src named dst.
7325
7326target_is_directory is required on Windows if the target is to be
7327 interpreted as a directory. (On Windows, symlink requires
7328 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7329 target_is_directory is ignored on non-Windows platforms.
7330
7331If dir_fd is not None, it should be a file descriptor open to a directory,
7332 and path should be relative; path will then be relative to that directory.
7333dir_fd may not be implemented on your platform.
7334 If it is unavailable, using it will raise a NotImplementedError.
7335
7336[clinic start generated code]*/
7337
Larry Hastings2f936352014-08-05 14:04:04 +10007338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007339os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007340 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007341/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007342{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007343#ifdef MS_WINDOWS
7344 DWORD result;
7345#else
7346 int result;
7347#endif
7348
Larry Hastings9cf065c2012-06-22 16:30:09 -07007349#ifdef MS_WINDOWS
7350 if (!check_CreateSymbolicLink()) {
7351 PyErr_SetString(PyExc_NotImplementedError,
7352 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007353 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007354 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007355 if (!win32_can_symlink) {
7356 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007357 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007358 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007359#endif
7360
Larry Hastings2f936352014-08-05 14:04:04 +10007361 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007362 PyErr_SetString(PyExc_ValueError,
7363 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007364 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007365 }
7366
7367#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007368
Larry Hastings9cf065c2012-06-22 16:30:09 -07007369 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007370 /* if src is a directory, ensure target_is_directory==1 */
7371 target_is_directory |= _check_dirW(src->wide, dst->wide);
7372 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7373 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007374 Py_END_ALLOW_THREADS
7375
Larry Hastings2f936352014-08-05 14:04:04 +10007376 if (!result)
7377 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378
7379#else
7380
7381 Py_BEGIN_ALLOW_THREADS
7382#if HAVE_SYMLINKAT
7383 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007384 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007385 else
7386#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007387 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007388 Py_END_ALLOW_THREADS
7389
Larry Hastings2f936352014-08-05 14:04:04 +10007390 if (result)
7391 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392#endif
7393
Larry Hastings2f936352014-08-05 14:04:04 +10007394 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007395}
7396#endif /* HAVE_SYMLINK */
7397
Larry Hastings9cf065c2012-06-22 16:30:09 -07007398
Brian Curtind40e6f72010-07-08 21:39:08 +00007399
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007400
Larry Hastings605a62d2012-06-24 04:33:36 -07007401static PyStructSequence_Field times_result_fields[] = {
7402 {"user", "user time"},
7403 {"system", "system time"},
7404 {"children_user", "user time of children"},
7405 {"children_system", "system time of children"},
7406 {"elapsed", "elapsed time since an arbitrary point in the past"},
7407 {NULL}
7408};
7409
7410PyDoc_STRVAR(times_result__doc__,
7411"times_result: Result from os.times().\n\n\
7412This object may be accessed either as a tuple of\n\
7413 (user, system, children_user, children_system, elapsed),\n\
7414or via the attributes user, system, children_user, children_system,\n\
7415and elapsed.\n\
7416\n\
7417See os.times for more information.");
7418
7419static PyStructSequence_Desc times_result_desc = {
7420 "times_result", /* name */
7421 times_result__doc__, /* doc */
7422 times_result_fields,
7423 5
7424};
7425
7426static PyTypeObject TimesResultType;
7427
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007428#ifdef MS_WINDOWS
7429#define HAVE_TIMES /* mandatory, for the method table */
7430#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007431
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007432#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007433
7434static PyObject *
7435build_times_result(double user, double system,
7436 double children_user, double children_system,
7437 double elapsed)
7438{
7439 PyObject *value = PyStructSequence_New(&TimesResultType);
7440 if (value == NULL)
7441 return NULL;
7442
7443#define SET(i, field) \
7444 { \
7445 PyObject *o = PyFloat_FromDouble(field); \
7446 if (!o) { \
7447 Py_DECREF(value); \
7448 return NULL; \
7449 } \
7450 PyStructSequence_SET_ITEM(value, i, o); \
7451 } \
7452
7453 SET(0, user);
7454 SET(1, system);
7455 SET(2, children_user);
7456 SET(3, children_system);
7457 SET(4, elapsed);
7458
7459#undef SET
7460
7461 return value;
7462}
7463
Larry Hastings605a62d2012-06-24 04:33:36 -07007464
Larry Hastings2f936352014-08-05 14:04:04 +10007465#ifndef MS_WINDOWS
7466#define NEED_TICKS_PER_SECOND
7467static long ticks_per_second = -1;
7468#endif /* MS_WINDOWS */
7469
7470/*[clinic input]
7471os.times
7472
7473Return a collection containing process timing information.
7474
7475The object returned behaves like a named tuple with these fields:
7476 (utime, stime, cutime, cstime, elapsed_time)
7477All fields are floating point numbers.
7478[clinic start generated code]*/
7479
Larry Hastings2f936352014-08-05 14:04:04 +10007480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007481os_times_impl(PyObject *module)
7482/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007483#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007484{
Victor Stinner8c62be82010-05-06 00:08:46 +00007485 FILETIME create, exit, kernel, user;
7486 HANDLE hProc;
7487 hProc = GetCurrentProcess();
7488 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7489 /* The fields of a FILETIME structure are the hi and lo part
7490 of a 64-bit value expressed in 100 nanosecond units.
7491 1e7 is one second in such units; 1e-7 the inverse.
7492 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7493 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007494 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 (double)(user.dwHighDateTime*429.4967296 +
7496 user.dwLowDateTime*1e-7),
7497 (double)(kernel.dwHighDateTime*429.4967296 +
7498 kernel.dwLowDateTime*1e-7),
7499 (double)0,
7500 (double)0,
7501 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007502}
Larry Hastings2f936352014-08-05 14:04:04 +10007503#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007504{
Larry Hastings2f936352014-08-05 14:04:04 +10007505
7506
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007507 struct tms t;
7508 clock_t c;
7509 errno = 0;
7510 c = times(&t);
7511 if (c == (clock_t) -1)
7512 return posix_error();
7513 return build_times_result(
7514 (double)t.tms_utime / ticks_per_second,
7515 (double)t.tms_stime / ticks_per_second,
7516 (double)t.tms_cutime / ticks_per_second,
7517 (double)t.tms_cstime / ticks_per_second,
7518 (double)c / ticks_per_second);
7519}
Larry Hastings2f936352014-08-05 14:04:04 +10007520#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007521#endif /* HAVE_TIMES */
7522
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007523
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007524#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007525/*[clinic input]
7526os.getsid
7527
7528 pid: pid_t
7529 /
7530
7531Call the system call getsid(pid) and return the result.
7532[clinic start generated code]*/
7533
Larry Hastings2f936352014-08-05 14:04:04 +10007534static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007535os_getsid_impl(PyObject *module, pid_t pid)
7536/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007537{
Victor Stinner8c62be82010-05-06 00:08:46 +00007538 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007539 sid = getsid(pid);
7540 if (sid < 0)
7541 return posix_error();
7542 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007543}
7544#endif /* HAVE_GETSID */
7545
7546
Guido van Rossumb6775db1994-08-01 11:34:53 +00007547#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007548/*[clinic input]
7549os.setsid
7550
7551Call the system call setsid().
7552[clinic start generated code]*/
7553
Larry Hastings2f936352014-08-05 14:04:04 +10007554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007555os_setsid_impl(PyObject *module)
7556/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007557{
Victor Stinner8c62be82010-05-06 00:08:46 +00007558 if (setsid() < 0)
7559 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007560 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007561}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007562#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007563
Larry Hastings2f936352014-08-05 14:04:04 +10007564
Guido van Rossumb6775db1994-08-01 11:34:53 +00007565#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007566/*[clinic input]
7567os.setpgid
7568
7569 pid: pid_t
7570 pgrp: pid_t
7571 /
7572
7573Call the system call setpgid(pid, pgrp).
7574[clinic start generated code]*/
7575
Larry Hastings2f936352014-08-05 14:04:04 +10007576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007577os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7578/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007579{
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 if (setpgid(pid, pgrp) < 0)
7581 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007582 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007583}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007584#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007585
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007586
Guido van Rossumb6775db1994-08-01 11:34:53 +00007587#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007588/*[clinic input]
7589os.tcgetpgrp
7590
7591 fd: int
7592 /
7593
7594Return the process group associated with the terminal specified by fd.
7595[clinic start generated code]*/
7596
Larry Hastings2f936352014-08-05 14:04:04 +10007597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007598os_tcgetpgrp_impl(PyObject *module, int fd)
7599/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007600{
7601 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007602 if (pgid < 0)
7603 return posix_error();
7604 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007605}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007606#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007608
Guido van Rossumb6775db1994-08-01 11:34:53 +00007609#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007610/*[clinic input]
7611os.tcsetpgrp
7612
7613 fd: int
7614 pgid: pid_t
7615 /
7616
7617Set the process group associated with the terminal specified by fd.
7618[clinic start generated code]*/
7619
Larry Hastings2f936352014-08-05 14:04:04 +10007620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007621os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7622/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007623{
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 if (tcsetpgrp(fd, pgid) < 0)
7625 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007626 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007627}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007628#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007629
Guido van Rossum687dd131993-05-17 08:34:16 +00007630/* Functions acting on file descriptors */
7631
Victor Stinnerdaf45552013-08-28 00:53:59 +02007632#ifdef O_CLOEXEC
7633extern int _Py_open_cloexec_works;
7634#endif
7635
Larry Hastings2f936352014-08-05 14:04:04 +10007636
7637/*[clinic input]
7638os.open -> int
7639 path: path_t
7640 flags: int
7641 mode: int = 0o777
7642 *
7643 dir_fd: dir_fd(requires='openat') = None
7644
7645# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7646
7647Open a file for low level IO. Returns a file descriptor (integer).
7648
7649If dir_fd is not None, it should be a file descriptor open to a directory,
7650 and path should be relative; path will then be relative to that directory.
7651dir_fd may not be implemented on your platform.
7652 If it is unavailable, using it will raise a NotImplementedError.
7653[clinic start generated code]*/
7654
Larry Hastings2f936352014-08-05 14:04:04 +10007655static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007656os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7657/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007658{
7659 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007660 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007661
Victor Stinnerdaf45552013-08-28 00:53:59 +02007662#ifdef O_CLOEXEC
7663 int *atomic_flag_works = &_Py_open_cloexec_works;
7664#elif !defined(MS_WINDOWS)
7665 int *atomic_flag_works = NULL;
7666#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007667
Victor Stinnerdaf45552013-08-28 00:53:59 +02007668#ifdef MS_WINDOWS
7669 flags |= O_NOINHERIT;
7670#elif defined(O_CLOEXEC)
7671 flags |= O_CLOEXEC;
7672#endif
7673
Steve Dower8fc89802015-04-12 00:26:27 -04007674 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007675 do {
7676 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007677#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007678 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007679#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007680#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007681 if (dir_fd != DEFAULT_DIR_FD)
7682 fd = openat(dir_fd, path->narrow, flags, mode);
7683 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007684#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007685 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007686#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007687 Py_END_ALLOW_THREADS
7688 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007689 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007690
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007691 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007692 if (!async_err)
7693 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007694 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007695 }
7696
Victor Stinnerdaf45552013-08-28 00:53:59 +02007697#ifndef MS_WINDOWS
7698 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7699 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007700 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007701 }
7702#endif
7703
Larry Hastings2f936352014-08-05 14:04:04 +10007704 return fd;
7705}
7706
7707
7708/*[clinic input]
7709os.close
7710
7711 fd: int
7712
7713Close a file descriptor.
7714[clinic start generated code]*/
7715
Barry Warsaw53699e91996-12-10 23:23:01 +00007716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007717os_close_impl(PyObject *module, int fd)
7718/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007719{
Larry Hastings2f936352014-08-05 14:04:04 +10007720 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007721 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7722 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7723 * for more details.
7724 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007726 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007728 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 Py_END_ALLOW_THREADS
7730 if (res < 0)
7731 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007732 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007733}
7734
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007735
Larry Hastings2f936352014-08-05 14:04:04 +10007736/*[clinic input]
7737os.closerange
7738
7739 fd_low: int
7740 fd_high: int
7741 /
7742
7743Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7744[clinic start generated code]*/
7745
Larry Hastings2f936352014-08-05 14:04:04 +10007746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007747os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7748/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007749{
7750 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007752 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007753 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007754 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007755 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 Py_END_ALLOW_THREADS
7757 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007758}
7759
7760
Larry Hastings2f936352014-08-05 14:04:04 +10007761/*[clinic input]
7762os.dup -> int
7763
7764 fd: int
7765 /
7766
7767Return a duplicate of a file descriptor.
7768[clinic start generated code]*/
7769
Larry Hastings2f936352014-08-05 14:04:04 +10007770static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007771os_dup_impl(PyObject *module, int fd)
7772/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007773{
7774 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007775}
7776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007777
Larry Hastings2f936352014-08-05 14:04:04 +10007778/*[clinic input]
7779os.dup2
7780 fd: int
7781 fd2: int
7782 inheritable: bool=True
7783
7784Duplicate file descriptor.
7785[clinic start generated code]*/
7786
Larry Hastings2f936352014-08-05 14:04:04 +10007787static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007788os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7789/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007790{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007791 int res;
7792#if defined(HAVE_DUP3) && \
7793 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7794 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7795 int dup3_works = -1;
7796#endif
7797
Steve Dower940f33a2016-09-08 11:21:54 -07007798 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007800
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007801 /* dup2() can fail with EINTR if the target FD is already open, because it
7802 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7803 * upon close(), and therefore below.
7804 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007805#ifdef MS_WINDOWS
7806 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007807 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007808 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007809 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007810 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007811 if (res < 0)
7812 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007813
7814 /* Character files like console cannot be make non-inheritable */
7815 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7816 close(fd2);
7817 return NULL;
7818 }
7819
7820#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7821 Py_BEGIN_ALLOW_THREADS
7822 if (!inheritable)
7823 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7824 else
7825 res = dup2(fd, fd2);
7826 Py_END_ALLOW_THREADS
7827 if (res < 0)
7828 return posix_error();
7829
7830#else
7831
7832#ifdef HAVE_DUP3
7833 if (!inheritable && dup3_works != 0) {
7834 Py_BEGIN_ALLOW_THREADS
7835 res = dup3(fd, fd2, O_CLOEXEC);
7836 Py_END_ALLOW_THREADS
7837 if (res < 0) {
7838 if (dup3_works == -1)
7839 dup3_works = (errno != ENOSYS);
7840 if (dup3_works)
7841 return posix_error();
7842 }
7843 }
7844
7845 if (inheritable || dup3_works == 0)
7846 {
7847#endif
7848 Py_BEGIN_ALLOW_THREADS
7849 res = dup2(fd, fd2);
7850 Py_END_ALLOW_THREADS
7851 if (res < 0)
7852 return posix_error();
7853
7854 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7855 close(fd2);
7856 return NULL;
7857 }
7858#ifdef HAVE_DUP3
7859 }
7860#endif
7861
7862#endif
7863
Larry Hastings2f936352014-08-05 14:04:04 +10007864 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007865}
7866
Larry Hastings2f936352014-08-05 14:04:04 +10007867
Ross Lagerwall7807c352011-03-17 20:20:30 +02007868#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007869/*[clinic input]
7870os.lockf
7871
7872 fd: int
7873 An open file descriptor.
7874 command: int
7875 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7876 length: Py_off_t
7877 The number of bytes to lock, starting at the current position.
7878 /
7879
7880Apply, test or remove a POSIX lock on an open file descriptor.
7881
7882[clinic start generated code]*/
7883
Larry Hastings2f936352014-08-05 14:04:04 +10007884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007885os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7886/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007887{
7888 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007889
7890 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007891 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007892 Py_END_ALLOW_THREADS
7893
7894 if (res < 0)
7895 return posix_error();
7896
7897 Py_RETURN_NONE;
7898}
Larry Hastings2f936352014-08-05 14:04:04 +10007899#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007901
Larry Hastings2f936352014-08-05 14:04:04 +10007902/*[clinic input]
7903os.lseek -> Py_off_t
7904
7905 fd: int
7906 position: Py_off_t
7907 how: int
7908 /
7909
7910Set the position of a file descriptor. Return the new position.
7911
7912Return the new cursor position in number of bytes
7913relative to the beginning of the file.
7914[clinic start generated code]*/
7915
Larry Hastings2f936352014-08-05 14:04:04 +10007916static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007917os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7918/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007919{
7920 Py_off_t result;
7921
Guido van Rossum687dd131993-05-17 08:34:16 +00007922#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7924 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007925 case 0: how = SEEK_SET; break;
7926 case 1: how = SEEK_CUR; break;
7927 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007929#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007930
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007932 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007933
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007935 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007936#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007937 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007938#else
Larry Hastings2f936352014-08-05 14:04:04 +10007939 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007940#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007941 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007943 if (result < 0)
7944 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007945
Larry Hastings2f936352014-08-05 14:04:04 +10007946 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007947}
7948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007949
Larry Hastings2f936352014-08-05 14:04:04 +10007950/*[clinic input]
7951os.read
7952 fd: int
7953 length: Py_ssize_t
7954 /
7955
7956Read from a file descriptor. Returns a bytes object.
7957[clinic start generated code]*/
7958
Larry Hastings2f936352014-08-05 14:04:04 +10007959static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007960os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7961/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007962{
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 Py_ssize_t n;
7964 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007965
7966 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 errno = EINVAL;
7968 return posix_error();
7969 }
Larry Hastings2f936352014-08-05 14:04:04 +10007970
7971#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007972 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007973 if (length > INT_MAX)
7974 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007975#endif
7976
7977 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 if (buffer == NULL)
7979 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007980
Victor Stinner66aab0c2015-03-19 22:53:20 +01007981 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7982 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007984 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 }
Larry Hastings2f936352014-08-05 14:04:04 +10007986
7987 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007989
Victor Stinner8c62be82010-05-06 00:08:46 +00007990 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007991}
7992
Ross Lagerwall7807c352011-03-17 20:20:30 +02007993#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7994 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007995static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007996iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007997{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007998 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007999 Py_ssize_t blen, total = 0;
8000
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008001 *iov = PyMem_New(struct iovec, cnt);
8002 if (*iov == NULL) {
8003 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008004 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008005 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008006
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008007 *buf = PyMem_New(Py_buffer, cnt);
8008 if (*buf == NULL) {
8009 PyMem_Del(*iov);
8010 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008011 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008012 }
8013
8014 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008015 PyObject *item = PySequence_GetItem(seq, i);
8016 if (item == NULL)
8017 goto fail;
8018 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8019 Py_DECREF(item);
8020 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008021 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008022 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008023 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008024 blen = (*buf)[i].len;
8025 (*iov)[i].iov_len = blen;
8026 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008027 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008028 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008029
8030fail:
8031 PyMem_Del(*iov);
8032 for (j = 0; j < i; j++) {
8033 PyBuffer_Release(&(*buf)[j]);
8034 }
8035 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008036 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008037}
8038
8039static void
8040iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8041{
8042 int i;
8043 PyMem_Del(iov);
8044 for (i = 0; i < cnt; i++) {
8045 PyBuffer_Release(&buf[i]);
8046 }
8047 PyMem_Del(buf);
8048}
8049#endif
8050
Larry Hastings2f936352014-08-05 14:04:04 +10008051
Ross Lagerwall7807c352011-03-17 20:20:30 +02008052#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008053/*[clinic input]
8054os.readv -> Py_ssize_t
8055
8056 fd: int
8057 buffers: object
8058 /
8059
8060Read from a file descriptor fd into an iterable of buffers.
8061
8062The buffers should be mutable buffers accepting bytes.
8063readv will transfer data into each buffer until it is full
8064and then move on to the next buffer in the sequence to hold
8065the rest of the data.
8066
8067readv returns the total number of bytes read,
8068which may be less than the total capacity of all the buffers.
8069[clinic start generated code]*/
8070
Larry Hastings2f936352014-08-05 14:04:04 +10008071static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008072os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8073/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008074{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008075 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008076 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008077 struct iovec *iov;
8078 Py_buffer *buf;
8079
Larry Hastings2f936352014-08-05 14:04:04 +10008080 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008081 PyErr_SetString(PyExc_TypeError,
8082 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008083 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008084 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008085
Larry Hastings2f936352014-08-05 14:04:04 +10008086 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008087 if (cnt < 0)
8088 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008089
8090 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8091 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008092
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008093 do {
8094 Py_BEGIN_ALLOW_THREADS
8095 n = readv(fd, iov, cnt);
8096 Py_END_ALLOW_THREADS
8097 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008098
8099 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008100 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008101 if (!async_err)
8102 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008103 return -1;
8104 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008105
Larry Hastings2f936352014-08-05 14:04:04 +10008106 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008107}
Larry Hastings2f936352014-08-05 14:04:04 +10008108#endif /* HAVE_READV */
8109
Ross Lagerwall7807c352011-03-17 20:20:30 +02008110
8111#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008112/*[clinic input]
8113# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8114os.pread
8115
8116 fd: int
8117 length: int
8118 offset: Py_off_t
8119 /
8120
8121Read a number of bytes from a file descriptor starting at a particular offset.
8122
8123Read length bytes from file descriptor fd, starting at offset bytes from
8124the beginning of the file. The file offset remains unchanged.
8125[clinic start generated code]*/
8126
Larry Hastings2f936352014-08-05 14:04:04 +10008127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008128os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8129/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008130{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008131 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008132 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008134
Larry Hastings2f936352014-08-05 14:04:04 +10008135 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136 errno = EINVAL;
8137 return posix_error();
8138 }
Larry Hastings2f936352014-08-05 14:04:04 +10008139 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008140 if (buffer == NULL)
8141 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008142
8143 do {
8144 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008145 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008146 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008147 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008148 Py_END_ALLOW_THREADS
8149 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8150
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151 if (n < 0) {
8152 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008153 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008154 }
Larry Hastings2f936352014-08-05 14:04:04 +10008155 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008156 _PyBytes_Resize(&buffer, n);
8157 return buffer;
8158}
Larry Hastings2f936352014-08-05 14:04:04 +10008159#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008160
Larry Hastings2f936352014-08-05 14:04:04 +10008161
8162/*[clinic input]
8163os.write -> Py_ssize_t
8164
8165 fd: int
8166 data: Py_buffer
8167 /
8168
8169Write a bytes object to a file descriptor.
8170[clinic start generated code]*/
8171
Larry Hastings2f936352014-08-05 14:04:04 +10008172static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008173os_write_impl(PyObject *module, int fd, Py_buffer *data)
8174/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008175{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008176 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008177}
8178
8179#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008180PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008181"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008182sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008183 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008184Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008185
Larry Hastings2f936352014-08-05 14:04:04 +10008186/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008187static PyObject *
8188posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8189{
8190 int in, out;
8191 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008192 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008193 off_t offset;
8194
8195#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8196#ifndef __APPLE__
8197 Py_ssize_t len;
8198#endif
8199 PyObject *headers = NULL, *trailers = NULL;
8200 Py_buffer *hbuf, *tbuf;
8201 off_t sbytes;
8202 struct sf_hdtr sf;
8203 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008204 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008205 static char *keywords[] = {"out", "in",
8206 "offset", "count",
8207 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008208
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008209 sf.headers = NULL;
8210 sf.trailers = NULL;
8211
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008212#ifdef __APPLE__
8213 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008214 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008215#else
8216 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008217 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008218#endif
8219 &headers, &trailers, &flags))
8220 return NULL;
8221 if (headers != NULL) {
8222 if (!PySequence_Check(headers)) {
8223 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008224 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008225 return NULL;
8226 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008227 Py_ssize_t i = PySequence_Size(headers);
8228 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008229 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008230 if (i > INT_MAX) {
8231 PyErr_SetString(PyExc_OverflowError,
8232 "sendfile() header is too large");
8233 return NULL;
8234 }
8235 if (i > 0) {
8236 sf.hdr_cnt = (int)i;
8237 i = iov_setup(&(sf.headers), &hbuf,
8238 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8239 if (i < 0)
8240 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008241#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008242 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008243#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008244 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245 }
8246 }
8247 if (trailers != NULL) {
8248 if (!PySequence_Check(trailers)) {
8249 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008250 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008251 return NULL;
8252 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008253 Py_ssize_t i = PySequence_Size(trailers);
8254 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008256 if (i > INT_MAX) {
8257 PyErr_SetString(PyExc_OverflowError,
8258 "sendfile() trailer is too large");
8259 return NULL;
8260 }
8261 if (i > 0) {
8262 sf.trl_cnt = (int)i;
8263 i = iov_setup(&(sf.trailers), &tbuf,
8264 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8265 if (i < 0)
8266 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008267#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008268 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008269#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008270 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008271 }
8272 }
8273
Steve Dower8fc89802015-04-12 00:26:27 -04008274 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008275 do {
8276 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008277#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008278 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008279#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008280 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008281#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008282 Py_END_ALLOW_THREADS
8283 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008284 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008285
8286 if (sf.headers != NULL)
8287 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8288 if (sf.trailers != NULL)
8289 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8290
8291 if (ret < 0) {
8292 if ((errno == EAGAIN) || (errno == EBUSY)) {
8293 if (sbytes != 0) {
8294 // some data has been sent
8295 goto done;
8296 }
8297 else {
8298 // no data has been sent; upper application is supposed
8299 // to retry on EAGAIN or EBUSY
8300 return posix_error();
8301 }
8302 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008303 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 }
8305 goto done;
8306
8307done:
8308 #if !defined(HAVE_LARGEFILE_SUPPORT)
8309 return Py_BuildValue("l", sbytes);
8310 #else
8311 return Py_BuildValue("L", sbytes);
8312 #endif
8313
8314#else
8315 Py_ssize_t count;
8316 PyObject *offobj;
8317 static char *keywords[] = {"out", "in",
8318 "offset", "count", NULL};
8319 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8320 keywords, &out, &in, &offobj, &count))
8321 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008322#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 do {
8325 Py_BEGIN_ALLOW_THREADS
8326 ret = sendfile(out, in, NULL, count);
8327 Py_END_ALLOW_THREADS
8328 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008329 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008330 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008331 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008332 }
8333#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008334 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008335 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008336
8337 do {
8338 Py_BEGIN_ALLOW_THREADS
8339 ret = sendfile(out, in, &offset, count);
8340 Py_END_ALLOW_THREADS
8341 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008342 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008343 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008344 return Py_BuildValue("n", ret);
8345#endif
8346}
Larry Hastings2f936352014-08-05 14:04:04 +10008347#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008348
Larry Hastings2f936352014-08-05 14:04:04 +10008349
8350/*[clinic input]
8351os.fstat
8352
8353 fd : int
8354
8355Perform a stat system call on the given file descriptor.
8356
8357Like stat(), but for an open file descriptor.
8358Equivalent to os.stat(fd).
8359[clinic start generated code]*/
8360
Larry Hastings2f936352014-08-05 14:04:04 +10008361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008362os_fstat_impl(PyObject *module, int fd)
8363/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008364{
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 STRUCT_STAT st;
8366 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008367 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008368
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008369 do {
8370 Py_BEGIN_ALLOW_THREADS
8371 res = FSTAT(fd, &st);
8372 Py_END_ALLOW_THREADS
8373 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008375#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008376 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008377#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008378 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008379#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 }
Tim Peters5aa91602002-01-30 05:46:57 +00008381
Victor Stinner4195b5c2012-02-08 23:03:19 +01008382 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008383}
8384
Larry Hastings2f936352014-08-05 14:04:04 +10008385
8386/*[clinic input]
8387os.isatty -> bool
8388 fd: int
8389 /
8390
8391Return True if the fd is connected to a terminal.
8392
8393Return True if the file descriptor is an open file descriptor
8394connected to the slave end of a terminal.
8395[clinic start generated code]*/
8396
Larry Hastings2f936352014-08-05 14:04:04 +10008397static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008398os_isatty_impl(PyObject *module, int fd)
8399/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008400{
Steve Dower8fc89802015-04-12 00:26:27 -04008401 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008402 _Py_BEGIN_SUPPRESS_IPH
8403 return_value = isatty(fd);
8404 _Py_END_SUPPRESS_IPH
8405 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008406}
8407
8408
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008409#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008410/*[clinic input]
8411os.pipe
8412
8413Create a pipe.
8414
8415Returns a tuple of two file descriptors:
8416 (read_fd, write_fd)
8417[clinic start generated code]*/
8418
Larry Hastings2f936352014-08-05 14:04:04 +10008419static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008420os_pipe_impl(PyObject *module)
8421/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008422{
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008424#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008426 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008428#else
8429 int res;
8430#endif
8431
8432#ifdef MS_WINDOWS
8433 attr.nLength = sizeof(attr);
8434 attr.lpSecurityDescriptor = NULL;
8435 attr.bInheritHandle = FALSE;
8436
8437 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008438 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008439 ok = CreatePipe(&read, &write, &attr, 0);
8440 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008441 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8442 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008443 if (fds[0] == -1 || fds[1] == -1) {
8444 CloseHandle(read);
8445 CloseHandle(write);
8446 ok = 0;
8447 }
8448 }
Steve Dowerc3630612016-11-19 18:41:16 -08008449 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008450 Py_END_ALLOW_THREADS
8451
Victor Stinner8c62be82010-05-06 00:08:46 +00008452 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008453 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008454#else
8455
8456#ifdef HAVE_PIPE2
8457 Py_BEGIN_ALLOW_THREADS
8458 res = pipe2(fds, O_CLOEXEC);
8459 Py_END_ALLOW_THREADS
8460
8461 if (res != 0 && errno == ENOSYS)
8462 {
8463#endif
8464 Py_BEGIN_ALLOW_THREADS
8465 res = pipe(fds);
8466 Py_END_ALLOW_THREADS
8467
8468 if (res == 0) {
8469 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8470 close(fds[0]);
8471 close(fds[1]);
8472 return NULL;
8473 }
8474 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8475 close(fds[0]);
8476 close(fds[1]);
8477 return NULL;
8478 }
8479 }
8480#ifdef HAVE_PIPE2
8481 }
8482#endif
8483
8484 if (res != 0)
8485 return PyErr_SetFromErrno(PyExc_OSError);
8486#endif /* !MS_WINDOWS */
8487 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008488}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008489#endif /* HAVE_PIPE */
8490
Larry Hastings2f936352014-08-05 14:04:04 +10008491
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008492#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008493/*[clinic input]
8494os.pipe2
8495
8496 flags: int
8497 /
8498
8499Create a pipe with flags set atomically.
8500
8501Returns a tuple of two file descriptors:
8502 (read_fd, write_fd)
8503
8504flags can be constructed by ORing together one or more of these values:
8505O_NONBLOCK, O_CLOEXEC.
8506[clinic start generated code]*/
8507
Larry Hastings2f936352014-08-05 14:04:04 +10008508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008509os_pipe2_impl(PyObject *module, int flags)
8510/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008511{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008512 int fds[2];
8513 int res;
8514
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008515 res = pipe2(fds, flags);
8516 if (res != 0)
8517 return posix_error();
8518 return Py_BuildValue("(ii)", fds[0], fds[1]);
8519}
8520#endif /* HAVE_PIPE2 */
8521
Larry Hastings2f936352014-08-05 14:04:04 +10008522
Ross Lagerwall7807c352011-03-17 20:20:30 +02008523#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008524/*[clinic input]
8525os.writev -> Py_ssize_t
8526 fd: int
8527 buffers: object
8528 /
8529
8530Iterate over buffers, and write the contents of each to a file descriptor.
8531
8532Returns the total number of bytes written.
8533buffers must be a sequence of bytes-like objects.
8534[clinic start generated code]*/
8535
Larry Hastings2f936352014-08-05 14:04:04 +10008536static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008537os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8538/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008539{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008540 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008541 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008542 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008543 struct iovec *iov;
8544 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008545
8546 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008547 PyErr_SetString(PyExc_TypeError,
8548 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008549 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008550 }
Larry Hastings2f936352014-08-05 14:04:04 +10008551 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008552 if (cnt < 0)
8553 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008554
Larry Hastings2f936352014-08-05 14:04:04 +10008555 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8556 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008557 }
8558
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008559 do {
8560 Py_BEGIN_ALLOW_THREADS
8561 result = writev(fd, iov, cnt);
8562 Py_END_ALLOW_THREADS
8563 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008564
8565 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008566 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008567 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008568
Georg Brandl306336b2012-06-24 12:55:33 +02008569 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008570}
Larry Hastings2f936352014-08-05 14:04:04 +10008571#endif /* HAVE_WRITEV */
8572
8573
8574#ifdef HAVE_PWRITE
8575/*[clinic input]
8576os.pwrite -> Py_ssize_t
8577
8578 fd: int
8579 buffer: Py_buffer
8580 offset: Py_off_t
8581 /
8582
8583Write bytes to a file descriptor starting at a particular offset.
8584
8585Write buffer to fd, starting at offset bytes from the beginning of
8586the file. Returns the number of bytes writte. Does not change the
8587current file offset.
8588[clinic start generated code]*/
8589
Larry Hastings2f936352014-08-05 14:04:04 +10008590static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008591os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8592/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008593{
8594 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008595 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008596
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008597 do {
8598 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008599 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008600 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008601 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008602 Py_END_ALLOW_THREADS
8603 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008604
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008605 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008606 posix_error();
8607 return size;
8608}
8609#endif /* HAVE_PWRITE */
8610
8611
8612#ifdef HAVE_MKFIFO
8613/*[clinic input]
8614os.mkfifo
8615
8616 path: path_t
8617 mode: int=0o666
8618 *
8619 dir_fd: dir_fd(requires='mkfifoat')=None
8620
8621Create a "fifo" (a POSIX named pipe).
8622
8623If dir_fd is not None, it should be a file descriptor open to a directory,
8624 and path should be relative; path will then be relative to that directory.
8625dir_fd may not be implemented on your platform.
8626 If it is unavailable, using it will raise a NotImplementedError.
8627[clinic start generated code]*/
8628
Larry Hastings2f936352014-08-05 14:04:04 +10008629static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008630os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8631/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008632{
8633 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008634 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008635
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008636 do {
8637 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008638#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008639 if (dir_fd != DEFAULT_DIR_FD)
8640 result = mkfifoat(dir_fd, path->narrow, mode);
8641 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008642#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008643 result = mkfifo(path->narrow, mode);
8644 Py_END_ALLOW_THREADS
8645 } while (result != 0 && errno == EINTR &&
8646 !(async_err = PyErr_CheckSignals()));
8647 if (result != 0)
8648 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008649
8650 Py_RETURN_NONE;
8651}
8652#endif /* HAVE_MKFIFO */
8653
8654
8655#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8656/*[clinic input]
8657os.mknod
8658
8659 path: path_t
8660 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008661 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008662 *
8663 dir_fd: dir_fd(requires='mknodat')=None
8664
8665Create a node in the file system.
8666
8667Create a node in the file system (file, device special file or named pipe)
8668at path. mode specifies both the permissions to use and the
8669type of node to be created, being combined (bitwise OR) with one of
8670S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8671device defines the newly created device special file (probably using
8672os.makedev()). Otherwise device is ignored.
8673
8674If dir_fd is not None, it should be a file descriptor open to a directory,
8675 and path should be relative; path will then be relative to that directory.
8676dir_fd may not be implemented on your platform.
8677 If it is unavailable, using it will raise a NotImplementedError.
8678[clinic start generated code]*/
8679
Larry Hastings2f936352014-08-05 14:04:04 +10008680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008681os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008682 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008683/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008684{
8685 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008686 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008687
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008688 do {
8689 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008690#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008691 if (dir_fd != DEFAULT_DIR_FD)
8692 result = mknodat(dir_fd, path->narrow, mode, device);
8693 else
Larry Hastings2f936352014-08-05 14:04:04 +10008694#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008695 result = mknod(path->narrow, mode, device);
8696 Py_END_ALLOW_THREADS
8697 } while (result != 0 && errno == EINTR &&
8698 !(async_err = PyErr_CheckSignals()));
8699 if (result != 0)
8700 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008701
8702 Py_RETURN_NONE;
8703}
8704#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8705
8706
8707#ifdef HAVE_DEVICE_MACROS
8708/*[clinic input]
8709os.major -> unsigned_int
8710
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008711 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008712 /
8713
8714Extracts a device major number from a raw device number.
8715[clinic start generated code]*/
8716
Larry Hastings2f936352014-08-05 14:04:04 +10008717static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008718os_major_impl(PyObject *module, dev_t device)
8719/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008720{
8721 return major(device);
8722}
8723
8724
8725/*[clinic input]
8726os.minor -> unsigned_int
8727
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008728 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008729 /
8730
8731Extracts a device minor number from a raw device number.
8732[clinic start generated code]*/
8733
Larry Hastings2f936352014-08-05 14:04:04 +10008734static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008735os_minor_impl(PyObject *module, dev_t device)
8736/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008737{
8738 return minor(device);
8739}
8740
8741
8742/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008743os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008744
8745 major: int
8746 minor: int
8747 /
8748
8749Composes a raw device number from the major and minor device numbers.
8750[clinic start generated code]*/
8751
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008752static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008753os_makedev_impl(PyObject *module, int major, int minor)
8754/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008755{
8756 return makedev(major, minor);
8757}
8758#endif /* HAVE_DEVICE_MACROS */
8759
8760
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008761#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008762/*[clinic input]
8763os.ftruncate
8764
8765 fd: int
8766 length: Py_off_t
8767 /
8768
8769Truncate a file, specified by file descriptor, to a specific length.
8770[clinic start generated code]*/
8771
Larry Hastings2f936352014-08-05 14:04:04 +10008772static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008773os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8774/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008775{
8776 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008777 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008778
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008779 do {
8780 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008781 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008782#ifdef MS_WINDOWS
8783 result = _chsize_s(fd, length);
8784#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008785 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008786#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008787 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008788 Py_END_ALLOW_THREADS
8789 } while (result != 0 && errno == EINTR &&
8790 !(async_err = PyErr_CheckSignals()));
8791 if (result != 0)
8792 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008793 Py_RETURN_NONE;
8794}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008795#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008796
8797
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008798#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008799/*[clinic input]
8800os.truncate
8801 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8802 length: Py_off_t
8803
8804Truncate a file, specified by path, to a specific length.
8805
8806On some platforms, path may also be specified as an open file descriptor.
8807 If this functionality is unavailable, using it raises an exception.
8808[clinic start generated code]*/
8809
Larry Hastings2f936352014-08-05 14:04:04 +10008810static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008811os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8812/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008813{
8814 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008815#ifdef MS_WINDOWS
8816 int fd;
8817#endif
8818
8819 if (path->fd != -1)
8820 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008821
8822 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008823 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008824#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008825 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008826 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008827 result = -1;
8828 else {
8829 result = _chsize_s(fd, length);
8830 close(fd);
8831 if (result < 0)
8832 errno = result;
8833 }
8834#else
8835 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008836#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008837 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008838 Py_END_ALLOW_THREADS
8839 if (result < 0)
8840 return path_error(path);
8841
8842 Py_RETURN_NONE;
8843}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008844#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008845
Ross Lagerwall7807c352011-03-17 20:20:30 +02008846
Victor Stinnerd6b17692014-09-30 12:20:05 +02008847/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8848 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8849 defined, which is the case in Python on AIX. AIX bug report:
8850 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8851#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8852# define POSIX_FADVISE_AIX_BUG
8853#endif
8854
Victor Stinnerec39e262014-09-30 12:35:58 +02008855
Victor Stinnerd6b17692014-09-30 12:20:05 +02008856#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008857/*[clinic input]
8858os.posix_fallocate
8859
8860 fd: int
8861 offset: Py_off_t
8862 length: Py_off_t
8863 /
8864
8865Ensure a file has allocated at least a particular number of bytes on disk.
8866
8867Ensure that the file specified by fd encompasses a range of bytes
8868starting at offset bytes from the beginning and continuing for length bytes.
8869[clinic start generated code]*/
8870
Larry Hastings2f936352014-08-05 14:04:04 +10008871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008872os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008873 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008874/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008875{
8876 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008877 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008878
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008879 do {
8880 Py_BEGIN_ALLOW_THREADS
8881 result = posix_fallocate(fd, offset, length);
8882 Py_END_ALLOW_THREADS
8883 } while (result != 0 && errno == EINTR &&
8884 !(async_err = PyErr_CheckSignals()));
8885 if (result != 0)
8886 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008887 Py_RETURN_NONE;
8888}
Victor Stinnerec39e262014-09-30 12:35:58 +02008889#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008890
Ross Lagerwall7807c352011-03-17 20:20:30 +02008891
Victor Stinnerd6b17692014-09-30 12:20:05 +02008892#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008893/*[clinic input]
8894os.posix_fadvise
8895
8896 fd: int
8897 offset: Py_off_t
8898 length: Py_off_t
8899 advice: int
8900 /
8901
8902Announce an intention to access data in a specific pattern.
8903
8904Announce an intention to access data in a specific pattern, thus allowing
8905the kernel to make optimizations.
8906The advice applies to the region of the file specified by fd starting at
8907offset and continuing for length bytes.
8908advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8909POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8910POSIX_FADV_DONTNEED.
8911[clinic start generated code]*/
8912
Larry Hastings2f936352014-08-05 14:04:04 +10008913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008914os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008915 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008916/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008917{
8918 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008919 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008920
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008921 do {
8922 Py_BEGIN_ALLOW_THREADS
8923 result = posix_fadvise(fd, offset, length, advice);
8924 Py_END_ALLOW_THREADS
8925 } while (result != 0 && errno == EINTR &&
8926 !(async_err = PyErr_CheckSignals()));
8927 if (result != 0)
8928 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008929 Py_RETURN_NONE;
8930}
Victor Stinnerec39e262014-09-30 12:35:58 +02008931#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008932
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008933#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008934
Fred Drake762e2061999-08-26 17:23:54 +00008935/* Save putenv() parameters as values here, so we can collect them when they
8936 * get re-set with another call for the same key. */
8937static PyObject *posix_putenv_garbage;
8938
Larry Hastings2f936352014-08-05 14:04:04 +10008939static void
8940posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008941{
Larry Hastings2f936352014-08-05 14:04:04 +10008942 /* Install the first arg and newstr in posix_putenv_garbage;
8943 * this will cause previous value to be collected. This has to
8944 * happen after the real putenv() call because the old value
8945 * was still accessible until then. */
8946 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8947 /* really not much we can do; just leak */
8948 PyErr_Clear();
8949 else
8950 Py_DECREF(value);
8951}
8952
8953
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008954#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008955/*[clinic input]
8956os.putenv
8957
8958 name: unicode
8959 value: unicode
8960 /
8961
8962Change or add an environment variable.
8963[clinic start generated code]*/
8964
Larry Hastings2f936352014-08-05 14:04:04 +10008965static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008966os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8967/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008968{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008969 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008970
8971 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8972 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008973 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008974 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008975 }
Larry Hastings2f936352014-08-05 14:04:04 +10008976 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008977 PyErr_Format(PyExc_ValueError,
8978 "the environment variable is longer than %u characters",
8979 _MAX_ENV);
8980 goto error;
8981 }
8982
Larry Hastings2f936352014-08-05 14:04:04 +10008983 env = PyUnicode_AsUnicode(unicode);
8984 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008985 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008986 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008988 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008990
Larry Hastings2f936352014-08-05 14:04:04 +10008991 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008992 Py_RETURN_NONE;
8993
8994error:
Larry Hastings2f936352014-08-05 14:04:04 +10008995 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008996 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008997}
Larry Hastings2f936352014-08-05 14:04:04 +10008998#else /* MS_WINDOWS */
8999/*[clinic input]
9000os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009001
Larry Hastings2f936352014-08-05 14:04:04 +10009002 name: FSConverter
9003 value: FSConverter
9004 /
9005
9006Change or add an environment variable.
9007[clinic start generated code]*/
9008
Larry Hastings2f936352014-08-05 14:04:04 +10009009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009010os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9011/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009012{
9013 PyObject *bytes = NULL;
9014 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009015 const char *name_string = PyBytes_AsString(name);
9016 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009017
9018 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9019 if (bytes == NULL) {
9020 PyErr_NoMemory();
9021 return NULL;
9022 }
9023
9024 env = PyBytes_AS_STRING(bytes);
9025 if (putenv(env)) {
9026 Py_DECREF(bytes);
9027 return posix_error();
9028 }
9029
9030 posix_putenv_garbage_setitem(name, bytes);
9031 Py_RETURN_NONE;
9032}
9033#endif /* MS_WINDOWS */
9034#endif /* HAVE_PUTENV */
9035
9036
9037#ifdef HAVE_UNSETENV
9038/*[clinic input]
9039os.unsetenv
9040 name: FSConverter
9041 /
9042
9043Delete an environment variable.
9044[clinic start generated code]*/
9045
Larry Hastings2f936352014-08-05 14:04:04 +10009046static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009047os_unsetenv_impl(PyObject *module, PyObject *name)
9048/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009049{
Victor Stinner984890f2011-11-24 13:53:38 +01009050#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009051 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009052#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009053
Victor Stinner984890f2011-11-24 13:53:38 +01009054#ifdef HAVE_BROKEN_UNSETENV
9055 unsetenv(PyBytes_AS_STRING(name));
9056#else
Victor Stinner65170952011-11-22 22:16:17 +01009057 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009058 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009059 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009060#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009061
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 /* Remove the key from posix_putenv_garbage;
9063 * this will cause it to be collected. This has to
9064 * happen after the real unsetenv() call because the
9065 * old value was still accessible until then.
9066 */
Victor Stinner65170952011-11-22 22:16:17 +01009067 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 /* really not much we can do; just leak */
9069 PyErr_Clear();
9070 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009071 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009072}
Larry Hastings2f936352014-08-05 14:04:04 +10009073#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009074
Larry Hastings2f936352014-08-05 14:04:04 +10009075
9076/*[clinic input]
9077os.strerror
9078
9079 code: int
9080 /
9081
9082Translate an error code to a message string.
9083[clinic start generated code]*/
9084
Larry Hastings2f936352014-08-05 14:04:04 +10009085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009086os_strerror_impl(PyObject *module, int code)
9087/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009088{
9089 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 if (message == NULL) {
9091 PyErr_SetString(PyExc_ValueError,
9092 "strerror() argument out of range");
9093 return NULL;
9094 }
Victor Stinner1b579672011-12-17 05:47:23 +01009095 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009096}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009097
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009098
Guido van Rossumc9641791998-08-04 15:26:23 +00009099#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009100#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009101/*[clinic input]
9102os.WCOREDUMP -> bool
9103
9104 status: int
9105 /
9106
9107Return True if the process returning status was dumped to a core file.
9108[clinic start generated code]*/
9109
Larry Hastings2f936352014-08-05 14:04:04 +10009110static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009111os_WCOREDUMP_impl(PyObject *module, int status)
9112/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009113{
9114 WAIT_TYPE wait_status;
9115 WAIT_STATUS_INT(wait_status) = status;
9116 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009117}
9118#endif /* WCOREDUMP */
9119
Larry Hastings2f936352014-08-05 14:04:04 +10009120
Fred Drake106c1a02002-04-23 15:58:02 +00009121#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009122/*[clinic input]
9123os.WIFCONTINUED -> bool
9124
9125 status: int
9126
9127Return True if a particular process was continued from a job control stop.
9128
9129Return True if the process returning status was continued from a
9130job control stop.
9131[clinic start generated code]*/
9132
Larry Hastings2f936352014-08-05 14:04:04 +10009133static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009134os_WIFCONTINUED_impl(PyObject *module, int status)
9135/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009136{
9137 WAIT_TYPE wait_status;
9138 WAIT_STATUS_INT(wait_status) = status;
9139 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009140}
9141#endif /* WIFCONTINUED */
9142
Larry Hastings2f936352014-08-05 14:04:04 +10009143
Guido van Rossumc9641791998-08-04 15:26:23 +00009144#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009145/*[clinic input]
9146os.WIFSTOPPED -> bool
9147
9148 status: int
9149
9150Return True if the process returning status was stopped.
9151[clinic start generated code]*/
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009154os_WIFSTOPPED_impl(PyObject *module, int status)
9155/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009156{
9157 WAIT_TYPE wait_status;
9158 WAIT_STATUS_INT(wait_status) = status;
9159 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009160}
9161#endif /* WIFSTOPPED */
9162
Larry Hastings2f936352014-08-05 14:04:04 +10009163
Guido van Rossumc9641791998-08-04 15:26:23 +00009164#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009165/*[clinic input]
9166os.WIFSIGNALED -> bool
9167
9168 status: int
9169
9170Return True if the process returning status was terminated by a signal.
9171[clinic start generated code]*/
9172
Larry Hastings2f936352014-08-05 14:04:04 +10009173static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009174os_WIFSIGNALED_impl(PyObject *module, int status)
9175/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009176{
9177 WAIT_TYPE wait_status;
9178 WAIT_STATUS_INT(wait_status) = status;
9179 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009180}
9181#endif /* WIFSIGNALED */
9182
Larry Hastings2f936352014-08-05 14:04:04 +10009183
Guido van Rossumc9641791998-08-04 15:26:23 +00009184#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009185/*[clinic input]
9186os.WIFEXITED -> bool
9187
9188 status: int
9189
9190Return True if the process returning status exited via the exit() system call.
9191[clinic start generated code]*/
9192
Larry Hastings2f936352014-08-05 14:04:04 +10009193static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009194os_WIFEXITED_impl(PyObject *module, int status)
9195/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009196{
9197 WAIT_TYPE wait_status;
9198 WAIT_STATUS_INT(wait_status) = status;
9199 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009200}
9201#endif /* WIFEXITED */
9202
Larry Hastings2f936352014-08-05 14:04:04 +10009203
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009204#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009205/*[clinic input]
9206os.WEXITSTATUS -> int
9207
9208 status: int
9209
9210Return the process return code from status.
9211[clinic start generated code]*/
9212
Larry Hastings2f936352014-08-05 14:04:04 +10009213static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009214os_WEXITSTATUS_impl(PyObject *module, int status)
9215/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009216{
9217 WAIT_TYPE wait_status;
9218 WAIT_STATUS_INT(wait_status) = status;
9219 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009220}
9221#endif /* WEXITSTATUS */
9222
Larry Hastings2f936352014-08-05 14:04:04 +10009223
Guido van Rossumc9641791998-08-04 15:26:23 +00009224#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009225/*[clinic input]
9226os.WTERMSIG -> int
9227
9228 status: int
9229
9230Return the signal that terminated the process that provided the status value.
9231[clinic start generated code]*/
9232
Larry Hastings2f936352014-08-05 14:04:04 +10009233static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009234os_WTERMSIG_impl(PyObject *module, int status)
9235/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009236{
9237 WAIT_TYPE wait_status;
9238 WAIT_STATUS_INT(wait_status) = status;
9239 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009240}
9241#endif /* WTERMSIG */
9242
Larry Hastings2f936352014-08-05 14:04:04 +10009243
Guido van Rossumc9641791998-08-04 15:26:23 +00009244#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009245/*[clinic input]
9246os.WSTOPSIG -> int
9247
9248 status: int
9249
9250Return the signal that stopped the process that provided the status value.
9251[clinic start generated code]*/
9252
Larry Hastings2f936352014-08-05 14:04:04 +10009253static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009254os_WSTOPSIG_impl(PyObject *module, int status)
9255/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009256{
9257 WAIT_TYPE wait_status;
9258 WAIT_STATUS_INT(wait_status) = status;
9259 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009260}
9261#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009262#endif /* HAVE_SYS_WAIT_H */
9263
9264
Thomas Wouters477c8d52006-05-27 19:21:47 +00009265#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009266#ifdef _SCO_DS
9267/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9268 needed definitions in sys/statvfs.h */
9269#define _SVID3
9270#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009271#include <sys/statvfs.h>
9272
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009273static PyObject*
9274_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9276 if (v == NULL)
9277 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009278
9279#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009280 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9281 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9282 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9283 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9284 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9285 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9286 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9287 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9288 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9289 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009290#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9292 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9293 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009294 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009296 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009298 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009300 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009302 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009304 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9306 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009307#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009308 if (PyErr_Occurred()) {
9309 Py_DECREF(v);
9310 return NULL;
9311 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009312
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009314}
9315
Larry Hastings2f936352014-08-05 14:04:04 +10009316
9317/*[clinic input]
9318os.fstatvfs
9319 fd: int
9320 /
9321
9322Perform an fstatvfs system call on the given fd.
9323
9324Equivalent to statvfs(fd).
9325[clinic start generated code]*/
9326
Larry Hastings2f936352014-08-05 14:04:04 +10009327static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009328os_fstatvfs_impl(PyObject *module, int fd)
9329/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009330{
9331 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009332 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009334
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009335 do {
9336 Py_BEGIN_ALLOW_THREADS
9337 result = fstatvfs(fd, &st);
9338 Py_END_ALLOW_THREADS
9339 } while (result != 0 && errno == EINTR &&
9340 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009341 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009342 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009343
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009345}
Larry Hastings2f936352014-08-05 14:04:04 +10009346#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009347
9348
Thomas Wouters477c8d52006-05-27 19:21:47 +00009349#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009350#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009351/*[clinic input]
9352os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009353
Larry Hastings2f936352014-08-05 14:04:04 +10009354 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9355
9356Perform a statvfs system call on the given path.
9357
9358path may always be specified as a string.
9359On some platforms, path may also be specified as an open file descriptor.
9360 If this functionality is unavailable, using it raises an exception.
9361[clinic start generated code]*/
9362
Larry Hastings2f936352014-08-05 14:04:04 +10009363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009364os_statvfs_impl(PyObject *module, path_t *path)
9365/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009366{
9367 int result;
9368 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009369
9370 Py_BEGIN_ALLOW_THREADS
9371#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009372 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009373#ifdef __APPLE__
9374 /* handle weak-linking on Mac OS X 10.3 */
9375 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009376 fd_specified("statvfs", path->fd);
9377 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009378 }
9379#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009380 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009381 }
9382 else
9383#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009384 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009385 Py_END_ALLOW_THREADS
9386
9387 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009388 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009389 }
9390
Larry Hastings2f936352014-08-05 14:04:04 +10009391 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009392}
Larry Hastings2f936352014-08-05 14:04:04 +10009393#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9394
Guido van Rossum94f6f721999-01-06 18:42:14 +00009395
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009396#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009397/*[clinic input]
9398os._getdiskusage
9399
9400 path: Py_UNICODE
9401
9402Return disk usage statistics about the given path as a (total, free) tuple.
9403[clinic start generated code]*/
9404
Larry Hastings2f936352014-08-05 14:04:04 +10009405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009406os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9407/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009408{
9409 BOOL retval;
9410 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009411
9412 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009413 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009414 Py_END_ALLOW_THREADS
9415 if (retval == 0)
9416 return PyErr_SetFromWindowsErr(0);
9417
9418 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9419}
Larry Hastings2f936352014-08-05 14:04:04 +10009420#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009421
9422
Fred Drakec9680921999-12-13 16:37:25 +00009423/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9424 * It maps strings representing configuration variable names to
9425 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009426 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009427 * rarely-used constants. There are three separate tables that use
9428 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009429 *
9430 * This code is always included, even if none of the interfaces that
9431 * need it are included. The #if hackery needed to avoid it would be
9432 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009433 */
9434struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009435 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009436 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009437};
9438
Fred Drake12c6e2d1999-12-14 21:25:03 +00009439static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009440conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009441 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009442{
Christian Heimes217cfd12007-12-02 14:31:20 +00009443 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009444 int value = _PyLong_AsInt(arg);
9445 if (value == -1 && PyErr_Occurred())
9446 return 0;
9447 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009448 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009449 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009450 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009451 /* look up the value in the table using a binary search */
9452 size_t lo = 0;
9453 size_t mid;
9454 size_t hi = tablesize;
9455 int cmp;
9456 const char *confname;
9457 if (!PyUnicode_Check(arg)) {
9458 PyErr_SetString(PyExc_TypeError,
9459 "configuration names must be strings or integers");
9460 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009462 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009463 if (confname == NULL)
9464 return 0;
9465 while (lo < hi) {
9466 mid = (lo + hi) / 2;
9467 cmp = strcmp(confname, table[mid].name);
9468 if (cmp < 0)
9469 hi = mid;
9470 else if (cmp > 0)
9471 lo = mid + 1;
9472 else {
9473 *valuep = table[mid].value;
9474 return 1;
9475 }
9476 }
9477 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9478 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009480}
9481
9482
9483#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9484static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009485#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009487#endif
9488#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009490#endif
Fred Drakec9680921999-12-13 16:37:25 +00009491#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009493#endif
9494#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009496#endif
9497#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009499#endif
9500#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009502#endif
9503#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009505#endif
9506#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009508#endif
9509#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009511#endif
9512#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009514#endif
9515#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009517#endif
9518#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009520#endif
9521#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
9524#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009526#endif
9527#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009529#endif
9530#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009532#endif
9533#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009535#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009536#ifdef _PC_ACL_ENABLED
9537 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9538#endif
9539#ifdef _PC_MIN_HOLE_SIZE
9540 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9541#endif
9542#ifdef _PC_ALLOC_SIZE_MIN
9543 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9544#endif
9545#ifdef _PC_REC_INCR_XFER_SIZE
9546 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9547#endif
9548#ifdef _PC_REC_MAX_XFER_SIZE
9549 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9550#endif
9551#ifdef _PC_REC_MIN_XFER_SIZE
9552 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9553#endif
9554#ifdef _PC_REC_XFER_ALIGN
9555 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9556#endif
9557#ifdef _PC_SYMLINK_MAX
9558 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9559#endif
9560#ifdef _PC_XATTR_ENABLED
9561 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9562#endif
9563#ifdef _PC_XATTR_EXISTS
9564 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9565#endif
9566#ifdef _PC_TIMESTAMP_RESOLUTION
9567 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9568#endif
Fred Drakec9680921999-12-13 16:37:25 +00009569};
9570
Fred Drakec9680921999-12-13 16:37:25 +00009571static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009572conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009573{
9574 return conv_confname(arg, valuep, posix_constants_pathconf,
9575 sizeof(posix_constants_pathconf)
9576 / sizeof(struct constdef));
9577}
9578#endif
9579
Larry Hastings2f936352014-08-05 14:04:04 +10009580
Fred Drakec9680921999-12-13 16:37:25 +00009581#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009582/*[clinic input]
9583os.fpathconf -> long
9584
9585 fd: int
9586 name: path_confname
9587 /
9588
9589Return the configuration limit name for the file descriptor fd.
9590
9591If there is no limit, return -1.
9592[clinic start generated code]*/
9593
Larry Hastings2f936352014-08-05 14:04:04 +10009594static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009595os_fpathconf_impl(PyObject *module, int fd, int name)
9596/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009597{
9598 long limit;
9599
9600 errno = 0;
9601 limit = fpathconf(fd, name);
9602 if (limit == -1 && errno != 0)
9603 posix_error();
9604
9605 return limit;
9606}
9607#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009608
9609
9610#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009611/*[clinic input]
9612os.pathconf -> long
9613 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9614 name: path_confname
9615
9616Return the configuration limit name for the file or directory path.
9617
9618If there is no limit, return -1.
9619On some platforms, path may also be specified as an open file descriptor.
9620 If this functionality is unavailable, using it raises an exception.
9621[clinic start generated code]*/
9622
Larry Hastings2f936352014-08-05 14:04:04 +10009623static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009624os_pathconf_impl(PyObject *module, path_t *path, int name)
9625/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009626{
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009628
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009630#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009631 if (path->fd != -1)
9632 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009633 else
9634#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009635 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 if (limit == -1 && errno != 0) {
9637 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009638 /* could be a path or name problem */
9639 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009640 else
Larry Hastings2f936352014-08-05 14:04:04 +10009641 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 }
Larry Hastings2f936352014-08-05 14:04:04 +10009643
9644 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009645}
Larry Hastings2f936352014-08-05 14:04:04 +10009646#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009647
9648#ifdef HAVE_CONFSTR
9649static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009650#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009652#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009653#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009655#endif
9656#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009658#endif
Fred Draked86ed291999-12-15 15:34:33 +00009659#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
9662#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
9665#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009667#endif
9668#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009670#endif
Fred Drakec9680921999-12-13 16:37:25 +00009671#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
9674#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009676#endif
9677#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
Fred Draked86ed291999-12-15 15:34:33 +00009695#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009697#endif
Fred Drakec9680921999-12-13 16:37:25 +00009698#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
Fred Draked86ed291999-12-15 15:34:33 +00009701#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009703#endif
9704#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009706#endif
9707#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009709#endif
9710#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009712#endif
Fred Drakec9680921999-12-13 16:37:25 +00009713#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
9716#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
9722#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
Fred Draked86ed291999-12-15 15:34:33 +00009761#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
9764#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009766#endif
9767#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009769#endif
9770#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009772#endif
9773#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009775#endif
9776#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009778#endif
9779#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009781#endif
9782#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009784#endif
9785#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009787#endif
9788#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009790#endif
9791#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009793#endif
9794#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009796#endif
9797#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
Fred Drakec9680921999-12-13 16:37:25 +00009800};
9801
9802static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009803conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009804{
9805 return conv_confname(arg, valuep, posix_constants_confstr,
9806 sizeof(posix_constants_confstr)
9807 / sizeof(struct constdef));
9808}
9809
Larry Hastings2f936352014-08-05 14:04:04 +10009810
9811/*[clinic input]
9812os.confstr
9813
9814 name: confstr_confname
9815 /
9816
9817Return a string-valued system configuration variable.
9818[clinic start generated code]*/
9819
Larry Hastings2f936352014-08-05 14:04:04 +10009820static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009821os_confstr_impl(PyObject *module, int name)
9822/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009823{
9824 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009825 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009826 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009827
Victor Stinnercb043522010-09-10 23:49:04 +00009828 errno = 0;
9829 len = confstr(name, buffer, sizeof(buffer));
9830 if (len == 0) {
9831 if (errno) {
9832 posix_error();
9833 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009834 }
9835 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009836 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009837 }
9838 }
Victor Stinnercb043522010-09-10 23:49:04 +00009839
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009840 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009841 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009842 char *buf = PyMem_Malloc(len);
9843 if (buf == NULL)
9844 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009845 len2 = confstr(name, buf, len);
9846 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009847 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009848 PyMem_Free(buf);
9849 }
9850 else
9851 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009852 return result;
9853}
Larry Hastings2f936352014-08-05 14:04:04 +10009854#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009855
9856
9857#ifdef HAVE_SYSCONF
9858static struct constdef posix_constants_sysconf[] = {
9859#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
Fred Draked86ed291999-12-15 15:34:33 +00009889#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009891#endif
9892#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009894#endif
Fred Drakec9680921999-12-13 16:37:25 +00009895#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
Fred Drakec9680921999-12-13 16:37:25 +00009898#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
Fred Draked86ed291999-12-15 15:34:33 +00009913#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009915#endif
Fred Drakec9680921999-12-13 16:37:25 +00009916#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
Fred Draked86ed291999-12-15 15:34:33 +00009931#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009933#endif
Fred Drakec9680921999-12-13 16:37:25 +00009934#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
Fred Draked86ed291999-12-15 15:34:33 +000010003#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010005#endif
Fred Drakec9680921999-12-13 16:37:25 +000010006#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
Fred Draked86ed291999-12-15 15:34:33 +000010015#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010017#endif
Fred Drakec9680921999-12-13 16:37:25 +000010018#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
Fred Draked86ed291999-12-15 15:34:33 +000010021#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010023#endif
10024#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010026#endif
Fred Drakec9680921999-12-13 16:37:25 +000010027#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
Fred Draked86ed291999-12-15 15:34:33 +000010039#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010041#endif
Fred Drakec9680921999-12-13 16:37:25 +000010042#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
Fred Draked86ed291999-12-15 15:34:33 +000010063#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010065#endif
Fred Drakec9680921999-12-13 16:37:25 +000010066#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
Fred Draked86ed291999-12-15 15:34:33 +000010072#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010074#endif
Fred Drakec9680921999-12-13 16:37:25 +000010075#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
Fred Draked86ed291999-12-15 15:34:33 +000010102#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010104#endif
10105#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010107#endif
Fred Drakec9680921999-12-13 16:37:25 +000010108#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
Fred Draked86ed291999-12-15 15:34:33 +000010213#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010215#endif
Fred Drakec9680921999-12-13 16:37:25 +000010216#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351};
10352
10353static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010354conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010355{
10356 return conv_confname(arg, valuep, posix_constants_sysconf,
10357 sizeof(posix_constants_sysconf)
10358 / sizeof(struct constdef));
10359}
10360
Larry Hastings2f936352014-08-05 14:04:04 +100010361
10362/*[clinic input]
10363os.sysconf -> long
10364 name: sysconf_confname
10365 /
10366
10367Return an integer-valued system configuration variable.
10368[clinic start generated code]*/
10369
Larry Hastings2f936352014-08-05 14:04:04 +100010370static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010371os_sysconf_impl(PyObject *module, int name)
10372/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010373{
10374 long value;
10375
10376 errno = 0;
10377 value = sysconf(name);
10378 if (value == -1 && errno != 0)
10379 posix_error();
10380 return value;
10381}
10382#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010383
10384
Fred Drakebec628d1999-12-15 18:31:10 +000010385/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010386 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010387 * the exported dictionaries that are used to publish information about the
10388 * names available on the host platform.
10389 *
10390 * Sorting the table at runtime ensures that the table is properly ordered
10391 * when used, even for platforms we're not able to test on. It also makes
10392 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010393 */
Fred Drakebec628d1999-12-15 18:31:10 +000010394
10395static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010396cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010397{
10398 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010400 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010402
10403 return strcmp(c1->name, c2->name);
10404}
10405
10406static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010407setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010408 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010409{
Fred Drakebec628d1999-12-15 18:31:10 +000010410 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010411 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010412
10413 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10414 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010415 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010417
Barry Warsaw3155db32000-04-13 15:20:40 +000010418 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 PyObject *o = PyLong_FromLong(table[i].value);
10420 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10421 Py_XDECREF(o);
10422 Py_DECREF(d);
10423 return -1;
10424 }
10425 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010426 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010427 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010428}
10429
Fred Drakebec628d1999-12-15 18:31:10 +000010430/* Return -1 on failure, 0 on success. */
10431static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010432setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010433{
10434#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010435 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010436 sizeof(posix_constants_pathconf)
10437 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010438 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010439 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010440#endif
10441#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010442 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010443 sizeof(posix_constants_confstr)
10444 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010445 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010446 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010447#endif
10448#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010449 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010450 sizeof(posix_constants_sysconf)
10451 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010452 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010453 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010454#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010455 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010456}
Fred Draked86ed291999-12-15 15:34:33 +000010457
10458
Larry Hastings2f936352014-08-05 14:04:04 +100010459/*[clinic input]
10460os.abort
10461
10462Abort the interpreter immediately.
10463
10464This function 'dumps core' or otherwise fails in the hardest way possible
10465on the hosting operating system. This function never returns.
10466[clinic start generated code]*/
10467
Larry Hastings2f936352014-08-05 14:04:04 +100010468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010469os_abort_impl(PyObject *module)
10470/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010471{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010472 abort();
10473 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010474#ifndef __clang__
10475 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10476 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10477 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010478 Py_FatalError("abort() called from Python code didn't abort!");
10479 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010480#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010481}
Fred Drakebec628d1999-12-15 18:31:10 +000010482
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010483#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010484/* Grab ShellExecute dynamically from shell32 */
10485static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010486static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10487 LPCWSTR, INT);
10488static int
10489check_ShellExecute()
10490{
10491 HINSTANCE hShell32;
10492
10493 /* only recheck */
10494 if (-1 == has_ShellExecute) {
10495 Py_BEGIN_ALLOW_THREADS
10496 hShell32 = LoadLibraryW(L"SHELL32");
10497 Py_END_ALLOW_THREADS
10498 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010499 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10500 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010501 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010502 } else {
10503 has_ShellExecute = 0;
10504 }
10505 }
10506 return has_ShellExecute;
10507}
10508
10509
Steve Dowercc16be82016-09-08 10:35:16 -070010510/*[clinic input]
10511os.startfile
10512 filepath: path_t
10513 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010514
Steve Dowercc16be82016-09-08 10:35:16 -070010515startfile(filepath [, operation])
10516
10517Start a file with its associated application.
10518
10519When "operation" is not specified or "open", this acts like
10520double-clicking the file in Explorer, or giving the file name as an
10521argument to the DOS "start" command: the file is opened with whatever
10522application (if any) its extension is associated.
10523When another "operation" is given, it specifies what should be done with
10524the file. A typical operation is "print".
10525
10526startfile returns as soon as the associated application is launched.
10527There is no option to wait for the application to close, and no way
10528to retrieve the application's exit status.
10529
10530The filepath is relative to the current directory. If you want to use
10531an absolute path, make sure the first character is not a slash ("/");
10532the underlying Win32 ShellExecute function doesn't work if it is.
10533[clinic start generated code]*/
10534
10535static PyObject *
10536os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10537/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10538{
10539 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010540
10541 if(!check_ShellExecute()) {
10542 /* If the OS doesn't have ShellExecute, return a
10543 NotImplementedError. */
10544 return PyErr_Format(PyExc_NotImplementedError,
10545 "startfile not available on this platform");
10546 }
10547
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010549 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010550 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 Py_END_ALLOW_THREADS
10552
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010554 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010555 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 }
Steve Dowercc16be82016-09-08 10:35:16 -070010557 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010558}
Larry Hastings2f936352014-08-05 14:04:04 +100010559#endif /* MS_WINDOWS */
10560
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010561
Martin v. Löwis438b5342002-12-27 10:16:42 +000010562#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010563/*[clinic input]
10564os.getloadavg
10565
10566Return average recent system load information.
10567
10568Return the number of processes in the system run queue averaged over
10569the last 1, 5, and 15 minutes as a tuple of three floats.
10570Raises OSError if the load average was unobtainable.
10571[clinic start generated code]*/
10572
Larry Hastings2f936352014-08-05 14:04:04 +100010573static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010574os_getloadavg_impl(PyObject *module)
10575/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010576{
10577 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010578 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010579 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10580 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010581 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010582 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010583}
Larry Hastings2f936352014-08-05 14:04:04 +100010584#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010585
Larry Hastings2f936352014-08-05 14:04:04 +100010586
10587/*[clinic input]
10588os.device_encoding
10589 fd: int
10590
10591Return a string describing the encoding of a terminal's file descriptor.
10592
10593The file descriptor must be attached to a terminal.
10594If the device is not a terminal, return None.
10595[clinic start generated code]*/
10596
Larry Hastings2f936352014-08-05 14:04:04 +100010597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010598os_device_encoding_impl(PyObject *module, int fd)
10599/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010600{
Brett Cannonefb00c02012-02-29 18:31:31 -050010601 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010602}
10603
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010604
Larry Hastings2f936352014-08-05 14:04:04 +100010605#ifdef HAVE_SETRESUID
10606/*[clinic input]
10607os.setresuid
10608
10609 ruid: uid_t
10610 euid: uid_t
10611 suid: uid_t
10612 /
10613
10614Set the current process's real, effective, and saved user ids.
10615[clinic start generated code]*/
10616
Larry Hastings2f936352014-08-05 14:04:04 +100010617static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010618os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10619/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010620{
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 if (setresuid(ruid, euid, suid) < 0)
10622 return posix_error();
10623 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010624}
Larry Hastings2f936352014-08-05 14:04:04 +100010625#endif /* HAVE_SETRESUID */
10626
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010627
10628#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010629/*[clinic input]
10630os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010631
Larry Hastings2f936352014-08-05 14:04:04 +100010632 rgid: gid_t
10633 egid: gid_t
10634 sgid: gid_t
10635 /
10636
10637Set the current process's real, effective, and saved group ids.
10638[clinic start generated code]*/
10639
Larry Hastings2f936352014-08-05 14:04:04 +100010640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010641os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10642/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010643{
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 if (setresgid(rgid, egid, sgid) < 0)
10645 return posix_error();
10646 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010647}
Larry Hastings2f936352014-08-05 14:04:04 +100010648#endif /* HAVE_SETRESGID */
10649
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010650
10651#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010652/*[clinic input]
10653os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010654
Larry Hastings2f936352014-08-05 14:04:04 +100010655Return a tuple of the current process's real, effective, and saved user ids.
10656[clinic start generated code]*/
10657
Larry Hastings2f936352014-08-05 14:04:04 +100010658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010659os_getresuid_impl(PyObject *module)
10660/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010661{
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 if (getresuid(&ruid, &euid, &suid) < 0)
10664 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010665 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10666 _PyLong_FromUid(euid),
10667 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010668}
Larry Hastings2f936352014-08-05 14:04:04 +100010669#endif /* HAVE_GETRESUID */
10670
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010671
10672#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010673/*[clinic input]
10674os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010675
Larry Hastings2f936352014-08-05 14:04:04 +100010676Return a tuple of the current process's real, effective, and saved group ids.
10677[clinic start generated code]*/
10678
Larry Hastings2f936352014-08-05 14:04:04 +100010679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010680os_getresgid_impl(PyObject *module)
10681/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010682{
10683 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 if (getresgid(&rgid, &egid, &sgid) < 0)
10685 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010686 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10687 _PyLong_FromGid(egid),
10688 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010689}
Larry Hastings2f936352014-08-05 14:04:04 +100010690#endif /* HAVE_GETRESGID */
10691
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010692
Benjamin Peterson9428d532011-09-14 11:45:52 -040010693#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010694/*[clinic input]
10695os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010696
Larry Hastings2f936352014-08-05 14:04:04 +100010697 path: path_t(allow_fd=True)
10698 attribute: path_t
10699 *
10700 follow_symlinks: bool = True
10701
10702Return the value of extended attribute attribute on path.
10703
10704path may be either a string or an open file descriptor.
10705If follow_symlinks is False, and the last element of the path is a symbolic
10706 link, getxattr will examine the symbolic link itself instead of the file
10707 the link points to.
10708
10709[clinic start generated code]*/
10710
Larry Hastings2f936352014-08-05 14:04:04 +100010711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010712os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010713 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010714/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010715{
10716 Py_ssize_t i;
10717 PyObject *buffer = NULL;
10718
10719 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10720 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010721
Larry Hastings9cf065c2012-06-22 16:30:09 -070010722 for (i = 0; ; i++) {
10723 void *ptr;
10724 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010725 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010726 Py_ssize_t buffer_size = buffer_sizes[i];
10727 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010728 path_error(path);
10729 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010730 }
10731 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10732 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010733 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010734 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010735
Larry Hastings9cf065c2012-06-22 16:30:09 -070010736 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010737 if (path->fd >= 0)
10738 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010740 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741 else
Larry Hastings2f936352014-08-05 14:04:04 +100010742 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010744
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745 if (result < 0) {
10746 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747 if (errno == ERANGE)
10748 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010749 path_error(path);
10750 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010752
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 if (result != buffer_size) {
10754 /* Can only shrink. */
10755 _PyBytes_Resize(&buffer, result);
10756 }
10757 break;
10758 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010759
Larry Hastings9cf065c2012-06-22 16:30:09 -070010760 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010761}
10762
Larry Hastings2f936352014-08-05 14:04:04 +100010763
10764/*[clinic input]
10765os.setxattr
10766
10767 path: path_t(allow_fd=True)
10768 attribute: path_t
10769 value: Py_buffer
10770 flags: int = 0
10771 *
10772 follow_symlinks: bool = True
10773
10774Set extended attribute attribute on path to value.
10775
10776path may be either a string or an open file descriptor.
10777If follow_symlinks is False, and the last element of the path is a symbolic
10778 link, setxattr will modify the symbolic link itself instead of the file
10779 the link points to.
10780
10781[clinic start generated code]*/
10782
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010784os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010785 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010786/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010787{
Larry Hastings2f936352014-08-05 14:04:04 +100010788 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010789
Larry Hastings2f936352014-08-05 14:04:04 +100010790 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010791 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792
Benjamin Peterson799bd802011-08-31 22:15:17 -040010793 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010794 if (path->fd > -1)
10795 result = fsetxattr(path->fd, attribute->narrow,
10796 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010797 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010798 result = setxattr(path->narrow, attribute->narrow,
10799 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800 else
Larry Hastings2f936352014-08-05 14:04:04 +100010801 result = lsetxattr(path->narrow, attribute->narrow,
10802 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010803 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010804
Larry Hastings9cf065c2012-06-22 16:30:09 -070010805 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010806 path_error(path);
10807 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010808 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010809
Larry Hastings2f936352014-08-05 14:04:04 +100010810 Py_RETURN_NONE;
10811}
10812
10813
10814/*[clinic input]
10815os.removexattr
10816
10817 path: path_t(allow_fd=True)
10818 attribute: path_t
10819 *
10820 follow_symlinks: bool = True
10821
10822Remove extended attribute attribute on path.
10823
10824path may be either a string or an open file descriptor.
10825If follow_symlinks is False, and the last element of the path is a symbolic
10826 link, removexattr will modify the symbolic link itself instead of the file
10827 the link points to.
10828
10829[clinic start generated code]*/
10830
Larry Hastings2f936352014-08-05 14:04:04 +100010831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010832os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010833 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010834/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010835{
10836 ssize_t result;
10837
10838 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10839 return NULL;
10840
10841 Py_BEGIN_ALLOW_THREADS;
10842 if (path->fd > -1)
10843 result = fremovexattr(path->fd, attribute->narrow);
10844 else if (follow_symlinks)
10845 result = removexattr(path->narrow, attribute->narrow);
10846 else
10847 result = lremovexattr(path->narrow, attribute->narrow);
10848 Py_END_ALLOW_THREADS;
10849
10850 if (result) {
10851 return path_error(path);
10852 }
10853
10854 Py_RETURN_NONE;
10855}
10856
10857
10858/*[clinic input]
10859os.listxattr
10860
10861 path: path_t(allow_fd=True, nullable=True) = None
10862 *
10863 follow_symlinks: bool = True
10864
10865Return a list of extended attributes on path.
10866
10867path may be either None, a string, or an open file descriptor.
10868if path is None, listxattr will examine the current directory.
10869If follow_symlinks is False, and the last element of the path is a symbolic
10870 link, listxattr will examine the symbolic link itself instead of the file
10871 the link points to.
10872[clinic start generated code]*/
10873
Larry Hastings2f936352014-08-05 14:04:04 +100010874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010875os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10876/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010877{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010878 Py_ssize_t i;
10879 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010880 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010881 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010882
Larry Hastings2f936352014-08-05 14:04:04 +100010883 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010884 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010885
Larry Hastings2f936352014-08-05 14:04:04 +100010886 name = path->narrow ? path->narrow : ".";
10887
Larry Hastings9cf065c2012-06-22 16:30:09 -070010888 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010889 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010890 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010891 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010892 Py_ssize_t buffer_size = buffer_sizes[i];
10893 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010894 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010895 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010896 break;
10897 }
10898 buffer = PyMem_MALLOC(buffer_size);
10899 if (!buffer) {
10900 PyErr_NoMemory();
10901 break;
10902 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010903
Larry Hastings9cf065c2012-06-22 16:30:09 -070010904 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010905 if (path->fd > -1)
10906 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010907 else if (follow_symlinks)
10908 length = listxattr(name, buffer, buffer_size);
10909 else
10910 length = llistxattr(name, buffer, buffer_size);
10911 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010912
Larry Hastings9cf065c2012-06-22 16:30:09 -070010913 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010914 if (errno == ERANGE) {
10915 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010916 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010917 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010918 }
Larry Hastings2f936352014-08-05 14:04:04 +100010919 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010920 break;
10921 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010922
Larry Hastings9cf065c2012-06-22 16:30:09 -070010923 result = PyList_New(0);
10924 if (!result) {
10925 goto exit;
10926 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010927
Larry Hastings9cf065c2012-06-22 16:30:09 -070010928 end = buffer + length;
10929 for (trace = start = buffer; trace != end; trace++) {
10930 if (!*trace) {
10931 int error;
10932 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10933 trace - start);
10934 if (!attribute) {
10935 Py_DECREF(result);
10936 result = NULL;
10937 goto exit;
10938 }
10939 error = PyList_Append(result, attribute);
10940 Py_DECREF(attribute);
10941 if (error) {
10942 Py_DECREF(result);
10943 result = NULL;
10944 goto exit;
10945 }
10946 start = trace + 1;
10947 }
10948 }
10949 break;
10950 }
10951exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010952 if (buffer)
10953 PyMem_FREE(buffer);
10954 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010955}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010956#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010957
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010958
Larry Hastings2f936352014-08-05 14:04:04 +100010959/*[clinic input]
10960os.urandom
10961
10962 size: Py_ssize_t
10963 /
10964
10965Return a bytes object containing random bytes suitable for cryptographic use.
10966[clinic start generated code]*/
10967
Larry Hastings2f936352014-08-05 14:04:04 +100010968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010969os_urandom_impl(PyObject *module, Py_ssize_t size)
10970/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010971{
10972 PyObject *bytes;
10973 int result;
10974
Georg Brandl2fb477c2012-02-21 00:33:36 +010010975 if (size < 0)
10976 return PyErr_Format(PyExc_ValueError,
10977 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010978 bytes = PyBytes_FromStringAndSize(NULL, size);
10979 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010980 return NULL;
10981
Victor Stinnere66987e2016-09-06 16:33:52 -070010982 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010983 if (result == -1) {
10984 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010985 return NULL;
10986 }
Larry Hastings2f936352014-08-05 14:04:04 +100010987 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010988}
10989
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010990/* Terminal size querying */
10991
10992static PyTypeObject TerminalSizeType;
10993
10994PyDoc_STRVAR(TerminalSize_docstring,
10995 "A tuple of (columns, lines) for holding terminal window size");
10996
10997static PyStructSequence_Field TerminalSize_fields[] = {
10998 {"columns", "width of the terminal window in characters"},
10999 {"lines", "height of the terminal window in characters"},
11000 {NULL, NULL}
11001};
11002
11003static PyStructSequence_Desc TerminalSize_desc = {
11004 "os.terminal_size",
11005 TerminalSize_docstring,
11006 TerminalSize_fields,
11007 2,
11008};
11009
11010#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011011/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011012PyDoc_STRVAR(termsize__doc__,
11013 "Return the size of the terminal window as (columns, lines).\n" \
11014 "\n" \
11015 "The optional argument fd (default standard output) specifies\n" \
11016 "which file descriptor should be queried.\n" \
11017 "\n" \
11018 "If the file descriptor is not connected to a terminal, an OSError\n" \
11019 "is thrown.\n" \
11020 "\n" \
11021 "This function will only be defined if an implementation is\n" \
11022 "available for this system.\n" \
11023 "\n" \
11024 "shutil.get_terminal_size is the high-level function which should \n" \
11025 "normally be used, os.get_terminal_size is the low-level implementation.");
11026
11027static PyObject*
11028get_terminal_size(PyObject *self, PyObject *args)
11029{
11030 int columns, lines;
11031 PyObject *termsize;
11032
11033 int fd = fileno(stdout);
11034 /* Under some conditions stdout may not be connected and
11035 * fileno(stdout) may point to an invalid file descriptor. For example
11036 * GUI apps don't have valid standard streams by default.
11037 *
11038 * If this happens, and the optional fd argument is not present,
11039 * the ioctl below will fail returning EBADF. This is what we want.
11040 */
11041
11042 if (!PyArg_ParseTuple(args, "|i", &fd))
11043 return NULL;
11044
11045#ifdef TERMSIZE_USE_IOCTL
11046 {
11047 struct winsize w;
11048 if (ioctl(fd, TIOCGWINSZ, &w))
11049 return PyErr_SetFromErrno(PyExc_OSError);
11050 columns = w.ws_col;
11051 lines = w.ws_row;
11052 }
11053#endif /* TERMSIZE_USE_IOCTL */
11054
11055#ifdef TERMSIZE_USE_CONIO
11056 {
11057 DWORD nhandle;
11058 HANDLE handle;
11059 CONSOLE_SCREEN_BUFFER_INFO csbi;
11060 switch (fd) {
11061 case 0: nhandle = STD_INPUT_HANDLE;
11062 break;
11063 case 1: nhandle = STD_OUTPUT_HANDLE;
11064 break;
11065 case 2: nhandle = STD_ERROR_HANDLE;
11066 break;
11067 default:
11068 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11069 }
11070 handle = GetStdHandle(nhandle);
11071 if (handle == NULL)
11072 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11073 if (handle == INVALID_HANDLE_VALUE)
11074 return PyErr_SetFromWindowsErr(0);
11075
11076 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11077 return PyErr_SetFromWindowsErr(0);
11078
11079 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11080 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11081 }
11082#endif /* TERMSIZE_USE_CONIO */
11083
11084 termsize = PyStructSequence_New(&TerminalSizeType);
11085 if (termsize == NULL)
11086 return NULL;
11087 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11088 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11089 if (PyErr_Occurred()) {
11090 Py_DECREF(termsize);
11091 return NULL;
11092 }
11093 return termsize;
11094}
11095#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11096
Larry Hastings2f936352014-08-05 14:04:04 +100011097
11098/*[clinic input]
11099os.cpu_count
11100
Charles-François Natali80d62e62015-08-13 20:37:08 +010011101Return the number of CPUs in the system; return None if indeterminable.
11102
11103This number is not equivalent to the number of CPUs the current process can
11104use. The number of usable CPUs can be obtained with
11105``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011106[clinic start generated code]*/
11107
Larry Hastings2f936352014-08-05 14:04:04 +100011108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011109os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011110/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011111{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011112 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011113#ifdef MS_WINDOWS
11114 SYSTEM_INFO sysinfo;
11115 GetSystemInfo(&sysinfo);
11116 ncpu = sysinfo.dwNumberOfProcessors;
11117#elif defined(__hpux)
11118 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11119#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11120 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011121#elif defined(__DragonFly__) || \
11122 defined(__OpenBSD__) || \
11123 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011124 defined(__NetBSD__) || \
11125 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011126 int mib[2];
11127 size_t len = sizeof(ncpu);
11128 mib[0] = CTL_HW;
11129 mib[1] = HW_NCPU;
11130 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11131 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011132#endif
11133 if (ncpu >= 1)
11134 return PyLong_FromLong(ncpu);
11135 else
11136 Py_RETURN_NONE;
11137}
11138
Victor Stinnerdaf45552013-08-28 00:53:59 +020011139
Larry Hastings2f936352014-08-05 14:04:04 +100011140/*[clinic input]
11141os.get_inheritable -> bool
11142
11143 fd: int
11144 /
11145
11146Get the close-on-exe flag of the specified file descriptor.
11147[clinic start generated code]*/
11148
Larry Hastings2f936352014-08-05 14:04:04 +100011149static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011150os_get_inheritable_impl(PyObject *module, int fd)
11151/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011152{
Steve Dower8fc89802015-04-12 00:26:27 -040011153 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011154 _Py_BEGIN_SUPPRESS_IPH
11155 return_value = _Py_get_inheritable(fd);
11156 _Py_END_SUPPRESS_IPH
11157 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011158}
11159
11160
11161/*[clinic input]
11162os.set_inheritable
11163 fd: int
11164 inheritable: int
11165 /
11166
11167Set the inheritable flag of the specified file descriptor.
11168[clinic start generated code]*/
11169
Larry Hastings2f936352014-08-05 14:04:04 +100011170static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011171os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11172/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011173{
Steve Dower8fc89802015-04-12 00:26:27 -040011174 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011175
Steve Dower8fc89802015-04-12 00:26:27 -040011176 _Py_BEGIN_SUPPRESS_IPH
11177 result = _Py_set_inheritable(fd, inheritable, NULL);
11178 _Py_END_SUPPRESS_IPH
11179 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011180 return NULL;
11181 Py_RETURN_NONE;
11182}
11183
11184
11185#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011186/*[clinic input]
11187os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011188 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011189 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011190
Larry Hastings2f936352014-08-05 14:04:04 +100011191Get the close-on-exe flag of the specified file descriptor.
11192[clinic start generated code]*/
11193
Larry Hastings2f936352014-08-05 14:04:04 +100011194static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011195os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011196/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011197{
11198 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011199
11200 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11201 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011202 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011203 }
11204
Larry Hastings2f936352014-08-05 14:04:04 +100011205 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011206}
11207
Victor Stinnerdaf45552013-08-28 00:53:59 +020011208
Larry Hastings2f936352014-08-05 14:04:04 +100011209/*[clinic input]
11210os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011211 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011212 inheritable: bool
11213 /
11214
11215Set the inheritable flag of the specified handle.
11216[clinic start generated code]*/
11217
Larry Hastings2f936352014-08-05 14:04:04 +100011218static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011219os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011220 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011221/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011222{
11223 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011224 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11225 PyErr_SetFromWindowsErr(0);
11226 return NULL;
11227 }
11228 Py_RETURN_NONE;
11229}
Larry Hastings2f936352014-08-05 14:04:04 +100011230#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011231
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011232#ifndef MS_WINDOWS
11233PyDoc_STRVAR(get_blocking__doc__,
11234 "get_blocking(fd) -> bool\n" \
11235 "\n" \
11236 "Get the blocking mode of the file descriptor:\n" \
11237 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11238
11239static PyObject*
11240posix_get_blocking(PyObject *self, PyObject *args)
11241{
11242 int fd;
11243 int blocking;
11244
11245 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11246 return NULL;
11247
Steve Dower8fc89802015-04-12 00:26:27 -040011248 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011249 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011250 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011251 if (blocking < 0)
11252 return NULL;
11253 return PyBool_FromLong(blocking);
11254}
11255
11256PyDoc_STRVAR(set_blocking__doc__,
11257 "set_blocking(fd, blocking)\n" \
11258 "\n" \
11259 "Set the blocking mode of the specified file descriptor.\n" \
11260 "Set the O_NONBLOCK flag if blocking is False,\n" \
11261 "clear the O_NONBLOCK flag otherwise.");
11262
11263static PyObject*
11264posix_set_blocking(PyObject *self, PyObject *args)
11265{
Steve Dower8fc89802015-04-12 00:26:27 -040011266 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011267
11268 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11269 return NULL;
11270
Steve Dower8fc89802015-04-12 00:26:27 -040011271 _Py_BEGIN_SUPPRESS_IPH
11272 result = _Py_set_blocking(fd, blocking);
11273 _Py_END_SUPPRESS_IPH
11274 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011275 return NULL;
11276 Py_RETURN_NONE;
11277}
11278#endif /* !MS_WINDOWS */
11279
11280
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011281/*[clinic input]
11282class os.DirEntry "DirEntry *" "&DirEntryType"
11283[clinic start generated code]*/
11284/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011285
11286typedef struct {
11287 PyObject_HEAD
11288 PyObject *name;
11289 PyObject *path;
11290 PyObject *stat;
11291 PyObject *lstat;
11292#ifdef MS_WINDOWS
11293 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011294 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011295 int got_file_index;
11296#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011297#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011298 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011299#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011300 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011301 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011302#endif
11303} DirEntry;
11304
11305static void
11306DirEntry_dealloc(DirEntry *entry)
11307{
11308 Py_XDECREF(entry->name);
11309 Py_XDECREF(entry->path);
11310 Py_XDECREF(entry->stat);
11311 Py_XDECREF(entry->lstat);
11312 Py_TYPE(entry)->tp_free((PyObject *)entry);
11313}
11314
11315/* Forward reference */
11316static int
11317DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11318
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011319/*[clinic input]
11320os.DirEntry.is_symlink -> bool
11321
11322Return True if the entry is a symbolic link; cached per entry.
11323[clinic start generated code]*/
11324
Victor Stinner6036e442015-03-08 01:58:04 +010011325static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011326os_DirEntry_is_symlink_impl(DirEntry *self)
11327/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011328{
11329#ifdef MS_WINDOWS
11330 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011331#elif defined(HAVE_DIRENT_D_TYPE)
11332 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011333 if (self->d_type != DT_UNKNOWN)
11334 return self->d_type == DT_LNK;
11335 else
11336 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011337#else
11338 /* POSIX without d_type */
11339 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011340#endif
11341}
11342
11343static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011344DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11345{
11346 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011347 STRUCT_STAT st;
11348 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011349
11350#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011351 if (!PyUnicode_FSDecoder(self->path, &ub))
11352 return NULL;
11353 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011354#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011355 if (!PyUnicode_FSConverter(self->path, &ub))
11356 return NULL;
11357 const char *path = PyBytes_AS_STRING(ub);
11358 if (self->dir_fd != DEFAULT_DIR_FD) {
11359#ifdef HAVE_FSTATAT
11360 result = fstatat(self->dir_fd, path, &st,
11361 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11362#else
11363 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11364 return NULL;
11365#endif /* HAVE_FSTATAT */
11366 }
11367 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011368#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011369 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011370 if (follow_symlinks)
11371 result = STAT(path, &st);
11372 else
11373 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011374 }
11375 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011376
11377 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011378 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011379
11380 return _pystat_fromstructstat(&st);
11381}
11382
11383static PyObject *
11384DirEntry_get_lstat(DirEntry *self)
11385{
11386 if (!self->lstat) {
11387#ifdef MS_WINDOWS
11388 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11389#else /* POSIX */
11390 self->lstat = DirEntry_fetch_stat(self, 0);
11391#endif
11392 }
11393 Py_XINCREF(self->lstat);
11394 return self->lstat;
11395}
11396
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011397/*[clinic input]
11398os.DirEntry.stat
11399 *
11400 follow_symlinks: bool = True
11401
11402Return stat_result object for the entry; cached per entry.
11403[clinic start generated code]*/
11404
Victor Stinner6036e442015-03-08 01:58:04 +010011405static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011406os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11407/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011408{
11409 if (!follow_symlinks)
11410 return DirEntry_get_lstat(self);
11411
11412 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011413 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011414 if (result == -1)
11415 return NULL;
11416 else if (result)
11417 self->stat = DirEntry_fetch_stat(self, 1);
11418 else
11419 self->stat = DirEntry_get_lstat(self);
11420 }
11421
11422 Py_XINCREF(self->stat);
11423 return self->stat;
11424}
11425
Victor Stinner6036e442015-03-08 01:58:04 +010011426/* Set exception and return -1 on error, 0 for False, 1 for True */
11427static int
11428DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11429{
11430 PyObject *stat = NULL;
11431 PyObject *st_mode = NULL;
11432 long mode;
11433 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011434#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011435 int is_symlink;
11436 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011437#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011438#ifdef MS_WINDOWS
11439 unsigned long dir_bits;
11440#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011441 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011442
11443#ifdef MS_WINDOWS
11444 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11445 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011446#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011447 is_symlink = self->d_type == DT_LNK;
11448 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11449#endif
11450
Victor Stinner35a97c02015-03-08 02:59:09 +010011451#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011452 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011453#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011454 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011455 if (!stat) {
11456 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11457 /* If file doesn't exist (anymore), then return False
11458 (i.e., say it's not a file/directory) */
11459 PyErr_Clear();
11460 return 0;
11461 }
11462 goto error;
11463 }
11464 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11465 if (!st_mode)
11466 goto error;
11467
11468 mode = PyLong_AsLong(st_mode);
11469 if (mode == -1 && PyErr_Occurred())
11470 goto error;
11471 Py_CLEAR(st_mode);
11472 Py_CLEAR(stat);
11473 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011474#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011475 }
11476 else if (is_symlink) {
11477 assert(mode_bits != S_IFLNK);
11478 result = 0;
11479 }
11480 else {
11481 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11482#ifdef MS_WINDOWS
11483 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11484 if (mode_bits == S_IFDIR)
11485 result = dir_bits != 0;
11486 else
11487 result = dir_bits == 0;
11488#else /* POSIX */
11489 if (mode_bits == S_IFDIR)
11490 result = self->d_type == DT_DIR;
11491 else
11492 result = self->d_type == DT_REG;
11493#endif
11494 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011495#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011496
11497 return result;
11498
11499error:
11500 Py_XDECREF(st_mode);
11501 Py_XDECREF(stat);
11502 return -1;
11503}
11504
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011505/*[clinic input]
11506os.DirEntry.is_dir -> bool
11507 *
11508 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011509
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011510Return True if the entry is a directory; cached per entry.
11511[clinic start generated code]*/
11512
11513static int
11514os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11515/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11516{
11517 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011518}
11519
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011520/*[clinic input]
11521os.DirEntry.is_file -> bool
11522 *
11523 follow_symlinks: bool = True
11524
11525Return True if the entry is a file; cached per entry.
11526[clinic start generated code]*/
11527
11528static int
11529os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11530/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011531{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011532 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011533}
11534
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011535/*[clinic input]
11536os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011537
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011538Return inode of the entry; cached per entry.
11539[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011540
11541static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011542os_DirEntry_inode_impl(DirEntry *self)
11543/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011544{
11545#ifdef MS_WINDOWS
11546 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011547 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011548 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011549 STRUCT_STAT stat;
11550 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011551
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011552 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011553 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011554 path = PyUnicode_AsUnicode(unicode);
11555 result = LSTAT(path, &stat);
11556 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011557
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011558 if (result != 0)
11559 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011560
11561 self->win32_file_index = stat.st_ino;
11562 self->got_file_index = 1;
11563 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011564 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11565 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011566#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011567 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11568 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011569#endif
11570}
11571
11572static PyObject *
11573DirEntry_repr(DirEntry *self)
11574{
11575 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11576}
11577
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011578/*[clinic input]
11579os.DirEntry.__fspath__
11580
11581Returns the path for the entry.
11582[clinic start generated code]*/
11583
Brett Cannon96881cd2016-06-10 14:37:21 -070011584static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011585os_DirEntry___fspath___impl(DirEntry *self)
11586/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011587{
11588 Py_INCREF(self->path);
11589 return self->path;
11590}
11591
Victor Stinner6036e442015-03-08 01:58:04 +010011592static PyMemberDef DirEntry_members[] = {
11593 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11594 "the entry's base filename, relative to scandir() \"path\" argument"},
11595 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11596 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11597 {NULL}
11598};
11599
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011600#include "clinic/posixmodule.c.h"
11601
Victor Stinner6036e442015-03-08 01:58:04 +010011602static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011603 OS_DIRENTRY_IS_DIR_METHODDEF
11604 OS_DIRENTRY_IS_FILE_METHODDEF
11605 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11606 OS_DIRENTRY_STAT_METHODDEF
11607 OS_DIRENTRY_INODE_METHODDEF
11608 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011609 {NULL}
11610};
11611
Benjamin Peterson5646de42015-04-12 17:56:34 -040011612static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011613 PyVarObject_HEAD_INIT(NULL, 0)
11614 MODNAME ".DirEntry", /* tp_name */
11615 sizeof(DirEntry), /* tp_basicsize */
11616 0, /* tp_itemsize */
11617 /* methods */
11618 (destructor)DirEntry_dealloc, /* tp_dealloc */
11619 0, /* tp_print */
11620 0, /* tp_getattr */
11621 0, /* tp_setattr */
11622 0, /* tp_compare */
11623 (reprfunc)DirEntry_repr, /* tp_repr */
11624 0, /* tp_as_number */
11625 0, /* tp_as_sequence */
11626 0, /* tp_as_mapping */
11627 0, /* tp_hash */
11628 0, /* tp_call */
11629 0, /* tp_str */
11630 0, /* tp_getattro */
11631 0, /* tp_setattro */
11632 0, /* tp_as_buffer */
11633 Py_TPFLAGS_DEFAULT, /* tp_flags */
11634 0, /* tp_doc */
11635 0, /* tp_traverse */
11636 0, /* tp_clear */
11637 0, /* tp_richcompare */
11638 0, /* tp_weaklistoffset */
11639 0, /* tp_iter */
11640 0, /* tp_iternext */
11641 DirEntry_methods, /* tp_methods */
11642 DirEntry_members, /* tp_members */
11643};
11644
11645#ifdef MS_WINDOWS
11646
11647static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011648join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011649{
11650 Py_ssize_t path_len;
11651 Py_ssize_t size;
11652 wchar_t *result;
11653 wchar_t ch;
11654
11655 if (!path_wide) { /* Default arg: "." */
11656 path_wide = L".";
11657 path_len = 1;
11658 }
11659 else {
11660 path_len = wcslen(path_wide);
11661 }
11662
11663 /* The +1's are for the path separator and the NUL */
11664 size = path_len + 1 + wcslen(filename) + 1;
11665 result = PyMem_New(wchar_t, size);
11666 if (!result) {
11667 PyErr_NoMemory();
11668 return NULL;
11669 }
11670 wcscpy(result, path_wide);
11671 if (path_len > 0) {
11672 ch = result[path_len - 1];
11673 if (ch != SEP && ch != ALTSEP && ch != L':')
11674 result[path_len++] = SEP;
11675 wcscpy(result + path_len, filename);
11676 }
11677 return result;
11678}
11679
11680static PyObject *
11681DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11682{
11683 DirEntry *entry;
11684 BY_HANDLE_FILE_INFORMATION file_info;
11685 ULONG reparse_tag;
11686 wchar_t *joined_path;
11687
11688 entry = PyObject_New(DirEntry, &DirEntryType);
11689 if (!entry)
11690 return NULL;
11691 entry->name = NULL;
11692 entry->path = NULL;
11693 entry->stat = NULL;
11694 entry->lstat = NULL;
11695 entry->got_file_index = 0;
11696
11697 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11698 if (!entry->name)
11699 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011700 if (path->narrow) {
11701 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11702 if (!entry->name)
11703 goto error;
11704 }
Victor Stinner6036e442015-03-08 01:58:04 +010011705
11706 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11707 if (!joined_path)
11708 goto error;
11709
11710 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11711 PyMem_Free(joined_path);
11712 if (!entry->path)
11713 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011714 if (path->narrow) {
11715 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11716 if (!entry->path)
11717 goto error;
11718 }
Victor Stinner6036e442015-03-08 01:58:04 +010011719
Steve Dowercc16be82016-09-08 10:35:16 -070011720 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011721 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11722
11723 return (PyObject *)entry;
11724
11725error:
11726 Py_DECREF(entry);
11727 return NULL;
11728}
11729
11730#else /* POSIX */
11731
11732static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011733join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011734{
11735 Py_ssize_t path_len;
11736 Py_ssize_t size;
11737 char *result;
11738
11739 if (!path_narrow) { /* Default arg: "." */
11740 path_narrow = ".";
11741 path_len = 1;
11742 }
11743 else {
11744 path_len = strlen(path_narrow);
11745 }
11746
11747 if (filename_len == -1)
11748 filename_len = strlen(filename);
11749
11750 /* The +1's are for the path separator and the NUL */
11751 size = path_len + 1 + filename_len + 1;
11752 result = PyMem_New(char, size);
11753 if (!result) {
11754 PyErr_NoMemory();
11755 return NULL;
11756 }
11757 strcpy(result, path_narrow);
11758 if (path_len > 0 && result[path_len - 1] != '/')
11759 result[path_len++] = '/';
11760 strcpy(result + path_len, filename);
11761 return result;
11762}
11763
11764static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011765DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011766 ino_t d_ino
11767#ifdef HAVE_DIRENT_D_TYPE
11768 , unsigned char d_type
11769#endif
11770 )
Victor Stinner6036e442015-03-08 01:58:04 +010011771{
11772 DirEntry *entry;
11773 char *joined_path;
11774
11775 entry = PyObject_New(DirEntry, &DirEntryType);
11776 if (!entry)
11777 return NULL;
11778 entry->name = NULL;
11779 entry->path = NULL;
11780 entry->stat = NULL;
11781 entry->lstat = NULL;
11782
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011783 if (path->fd != -1) {
11784 entry->dir_fd = path->fd;
11785 joined_path = NULL;
11786 }
11787 else {
11788 entry->dir_fd = DEFAULT_DIR_FD;
11789 joined_path = join_path_filename(path->narrow, name, name_len);
11790 if (!joined_path)
11791 goto error;
11792 }
Victor Stinner6036e442015-03-08 01:58:04 +010011793
11794 if (!path->narrow || !PyBytes_Check(path->object)) {
11795 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011796 if (joined_path)
11797 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011798 }
11799 else {
11800 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011801 if (joined_path)
11802 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011803 }
11804 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011805 if (!entry->name)
11806 goto error;
11807
11808 if (path->fd != -1) {
11809 entry->path = entry->name;
11810 Py_INCREF(entry->path);
11811 }
11812 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011813 goto error;
11814
Victor Stinner35a97c02015-03-08 02:59:09 +010011815#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011816 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011817#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011818 entry->d_ino = d_ino;
11819
11820 return (PyObject *)entry;
11821
11822error:
11823 Py_XDECREF(entry);
11824 return NULL;
11825}
11826
11827#endif
11828
11829
11830typedef struct {
11831 PyObject_HEAD
11832 path_t path;
11833#ifdef MS_WINDOWS
11834 HANDLE handle;
11835 WIN32_FIND_DATAW file_data;
11836 int first_time;
11837#else /* POSIX */
11838 DIR *dirp;
11839#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011840#ifdef HAVE_FDOPENDIR
11841 int fd;
11842#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011843} ScandirIterator;
11844
11845#ifdef MS_WINDOWS
11846
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011847static int
11848ScandirIterator_is_closed(ScandirIterator *iterator)
11849{
11850 return iterator->handle == INVALID_HANDLE_VALUE;
11851}
11852
Victor Stinner6036e442015-03-08 01:58:04 +010011853static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011854ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011855{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011856 HANDLE handle = iterator->handle;
11857
11858 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011859 return;
11860
Victor Stinner6036e442015-03-08 01:58:04 +010011861 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011862 Py_BEGIN_ALLOW_THREADS
11863 FindClose(handle);
11864 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011865}
11866
11867static PyObject *
11868ScandirIterator_iternext(ScandirIterator *iterator)
11869{
11870 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11871 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011872 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011873
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011874 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011875 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011876 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011877
11878 while (1) {
11879 if (!iterator->first_time) {
11880 Py_BEGIN_ALLOW_THREADS
11881 success = FindNextFileW(iterator->handle, file_data);
11882 Py_END_ALLOW_THREADS
11883 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011884 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011885 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011886 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011887 break;
11888 }
11889 }
11890 iterator->first_time = 0;
11891
11892 /* Skip over . and .. */
11893 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011894 wcscmp(file_data->cFileName, L"..") != 0) {
11895 entry = DirEntry_from_find_data(&iterator->path, file_data);
11896 if (!entry)
11897 break;
11898 return entry;
11899 }
Victor Stinner6036e442015-03-08 01:58:04 +010011900
11901 /* Loop till we get a non-dot directory or finish iterating */
11902 }
11903
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011904 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011905 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011906 return NULL;
11907}
11908
11909#else /* POSIX */
11910
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011911static int
11912ScandirIterator_is_closed(ScandirIterator *iterator)
11913{
11914 return !iterator->dirp;
11915}
11916
Victor Stinner6036e442015-03-08 01:58:04 +010011917static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011918ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011919{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011920 DIR *dirp = iterator->dirp;
11921
11922 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011923 return;
11924
Victor Stinner6036e442015-03-08 01:58:04 +010011925 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011926 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011927#ifdef HAVE_FDOPENDIR
11928 if (iterator->path.fd != -1)
11929 rewinddir(dirp);
11930#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011931 closedir(dirp);
11932 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011933 return;
11934}
11935
11936static PyObject *
11937ScandirIterator_iternext(ScandirIterator *iterator)
11938{
11939 struct dirent *direntp;
11940 Py_ssize_t name_len;
11941 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011942 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011943
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011944 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011945 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011946 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011947
11948 while (1) {
11949 errno = 0;
11950 Py_BEGIN_ALLOW_THREADS
11951 direntp = readdir(iterator->dirp);
11952 Py_END_ALLOW_THREADS
11953
11954 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011955 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011956 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011957 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011958 break;
11959 }
11960
11961 /* Skip over . and .. */
11962 name_len = NAMLEN(direntp);
11963 is_dot = direntp->d_name[0] == '.' &&
11964 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11965 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011966 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011967 name_len, direntp->d_ino
11968#ifdef HAVE_DIRENT_D_TYPE
11969 , direntp->d_type
11970#endif
11971 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011972 if (!entry)
11973 break;
11974 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011975 }
11976
11977 /* Loop till we get a non-dot directory or finish iterating */
11978 }
11979
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011980 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011981 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011982 return NULL;
11983}
11984
11985#endif
11986
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011987static PyObject *
11988ScandirIterator_close(ScandirIterator *self, PyObject *args)
11989{
11990 ScandirIterator_closedir(self);
11991 Py_RETURN_NONE;
11992}
11993
11994static PyObject *
11995ScandirIterator_enter(PyObject *self, PyObject *args)
11996{
11997 Py_INCREF(self);
11998 return self;
11999}
12000
12001static PyObject *
12002ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12003{
12004 ScandirIterator_closedir(self);
12005 Py_RETURN_NONE;
12006}
12007
Victor Stinner6036e442015-03-08 01:58:04 +010012008static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012009ScandirIterator_finalize(ScandirIterator *iterator)
12010{
12011 PyObject *error_type, *error_value, *error_traceback;
12012
12013 /* Save the current exception, if any. */
12014 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12015
12016 if (!ScandirIterator_is_closed(iterator)) {
12017 ScandirIterator_closedir(iterator);
12018
12019 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12020 "unclosed scandir iterator %R", iterator)) {
12021 /* Spurious errors can appear at shutdown */
12022 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12023 PyErr_WriteUnraisable((PyObject *) iterator);
12024 }
12025 }
12026 }
12027
Victor Stinner7bfa4092016-03-23 00:43:54 +010012028 path_cleanup(&iterator->path);
12029
12030 /* Restore the saved exception. */
12031 PyErr_Restore(error_type, error_value, error_traceback);
12032}
12033
12034static void
Victor Stinner6036e442015-03-08 01:58:04 +010012035ScandirIterator_dealloc(ScandirIterator *iterator)
12036{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012037 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12038 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012039
Victor Stinner6036e442015-03-08 01:58:04 +010012040 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12041}
12042
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012043static PyMethodDef ScandirIterator_methods[] = {
12044 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12045 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12046 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12047 {NULL}
12048};
12049
Benjamin Peterson5646de42015-04-12 17:56:34 -040012050static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012051 PyVarObject_HEAD_INIT(NULL, 0)
12052 MODNAME ".ScandirIterator", /* tp_name */
12053 sizeof(ScandirIterator), /* tp_basicsize */
12054 0, /* tp_itemsize */
12055 /* methods */
12056 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12057 0, /* tp_print */
12058 0, /* tp_getattr */
12059 0, /* tp_setattr */
12060 0, /* tp_compare */
12061 0, /* tp_repr */
12062 0, /* tp_as_number */
12063 0, /* tp_as_sequence */
12064 0, /* tp_as_mapping */
12065 0, /* tp_hash */
12066 0, /* tp_call */
12067 0, /* tp_str */
12068 0, /* tp_getattro */
12069 0, /* tp_setattro */
12070 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012071 Py_TPFLAGS_DEFAULT
12072 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012073 0, /* tp_doc */
12074 0, /* tp_traverse */
12075 0, /* tp_clear */
12076 0, /* tp_richcompare */
12077 0, /* tp_weaklistoffset */
12078 PyObject_SelfIter, /* tp_iter */
12079 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012080 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012081 0, /* tp_members */
12082 0, /* tp_getset */
12083 0, /* tp_base */
12084 0, /* tp_dict */
12085 0, /* tp_descr_get */
12086 0, /* tp_descr_set */
12087 0, /* tp_dictoffset */
12088 0, /* tp_init */
12089 0, /* tp_alloc */
12090 0, /* tp_new */
12091 0, /* tp_free */
12092 0, /* tp_is_gc */
12093 0, /* tp_bases */
12094 0, /* tp_mro */
12095 0, /* tp_cache */
12096 0, /* tp_subclasses */
12097 0, /* tp_weaklist */
12098 0, /* tp_del */
12099 0, /* tp_version_tag */
12100 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012101};
12102
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012103/*[clinic input]
12104os.scandir
12105
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012106 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012107
12108Return an iterator of DirEntry objects for given path.
12109
12110path can be specified as either str, bytes or path-like object. If path
12111is bytes, the names of yielded DirEntry objects will also be bytes; in
12112all other circumstances they will be str.
12113
12114If path is None, uses the path='.'.
12115[clinic start generated code]*/
12116
Victor Stinner6036e442015-03-08 01:58:04 +010012117static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012118os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012119/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012120{
12121 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012122#ifdef MS_WINDOWS
12123 wchar_t *path_strW;
12124#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012125 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012126#ifdef HAVE_FDOPENDIR
12127 int fd = -1;
12128#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012129#endif
12130
12131 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12132 if (!iterator)
12133 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012134
12135#ifdef MS_WINDOWS
12136 iterator->handle = INVALID_HANDLE_VALUE;
12137#else
12138 iterator->dirp = NULL;
12139#endif
12140
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012141 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012142 /* Move the ownership to iterator->path */
12143 path->object = NULL;
12144 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012145
12146#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012147 iterator->first_time = 1;
12148
12149 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12150 if (!path_strW)
12151 goto error;
12152
12153 Py_BEGIN_ALLOW_THREADS
12154 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12155 Py_END_ALLOW_THREADS
12156
12157 PyMem_Free(path_strW);
12158
12159 if (iterator->handle == INVALID_HANDLE_VALUE) {
12160 path_error(&iterator->path);
12161 goto error;
12162 }
12163#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012164 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012165#ifdef HAVE_FDOPENDIR
12166 if (path->fd != -1) {
12167 /* closedir() closes the FD, so we duplicate it */
12168 fd = _Py_dup(path->fd);
12169 if (fd == -1)
12170 goto error;
12171
12172 Py_BEGIN_ALLOW_THREADS
12173 iterator->dirp = fdopendir(fd);
12174 Py_END_ALLOW_THREADS
12175 }
12176 else
12177#endif
12178 {
12179 if (iterator->path.narrow)
12180 path_str = iterator->path.narrow;
12181 else
12182 path_str = ".";
12183
12184 Py_BEGIN_ALLOW_THREADS
12185 iterator->dirp = opendir(path_str);
12186 Py_END_ALLOW_THREADS
12187 }
Victor Stinner6036e442015-03-08 01:58:04 +010012188
12189 if (!iterator->dirp) {
12190 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012191#ifdef HAVE_FDOPENDIR
12192 if (fd != -1) {
12193 Py_BEGIN_ALLOW_THREADS
12194 close(fd);
12195 Py_END_ALLOW_THREADS
12196 }
12197#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012198 goto error;
12199 }
12200#endif
12201
12202 return (PyObject *)iterator;
12203
12204error:
12205 Py_DECREF(iterator);
12206 return NULL;
12207}
12208
Ethan Furman410ef8e2016-06-04 12:06:26 -070012209/*
12210 Return the file system path representation of the object.
12211
12212 If the object is str or bytes, then allow it to pass through with
12213 an incremented refcount. If the object defines __fspath__(), then
12214 return the result of that method. All other types raise a TypeError.
12215*/
12216PyObject *
12217PyOS_FSPath(PyObject *path)
12218{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012219 /* For error message reasons, this function is manually inlined in
12220 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012221 _Py_IDENTIFIER(__fspath__);
12222 PyObject *func = NULL;
12223 PyObject *path_repr = NULL;
12224
12225 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12226 Py_INCREF(path);
12227 return path;
12228 }
12229
12230 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12231 if (NULL == func) {
12232 return PyErr_Format(PyExc_TypeError,
12233 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012234 "not %.200s",
12235 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012236 }
12237
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012238 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012239 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012240 if (NULL == path_repr) {
12241 return NULL;
12242 }
12243
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012244 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12245 PyErr_Format(PyExc_TypeError,
12246 "expected %.200s.__fspath__() to return str or bytes, "
12247 "not %.200s", Py_TYPE(path)->tp_name,
12248 Py_TYPE(path_repr)->tp_name);
12249 Py_DECREF(path_repr);
12250 return NULL;
12251 }
12252
Ethan Furman410ef8e2016-06-04 12:06:26 -070012253 return path_repr;
12254}
12255
12256/*[clinic input]
12257os.fspath
12258
12259 path: object
12260
12261Return the file system path representation of the object.
12262
Brett Cannonb4f43e92016-06-09 14:32:08 -070012263If the object is str or bytes, then allow it to pass through as-is. If the
12264object defines __fspath__(), then return the result of that method. All other
12265types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012266[clinic start generated code]*/
12267
12268static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012269os_fspath_impl(PyObject *module, PyObject *path)
12270/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012271{
12272 return PyOS_FSPath(path);
12273}
Victor Stinner6036e442015-03-08 01:58:04 +010012274
Victor Stinner9b1f4742016-09-06 16:18:52 -070012275#ifdef HAVE_GETRANDOM_SYSCALL
12276/*[clinic input]
12277os.getrandom
12278
12279 size: Py_ssize_t
12280 flags: int=0
12281
12282Obtain a series of random bytes.
12283[clinic start generated code]*/
12284
12285static PyObject *
12286os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12287/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12288{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012289 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012290 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012291
12292 if (size < 0) {
12293 errno = EINVAL;
12294 return posix_error();
12295 }
12296
Victor Stinnerec2319c2016-09-20 23:00:59 +020012297 bytes = PyBytes_FromStringAndSize(NULL, size);
12298 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012299 PyErr_NoMemory();
12300 return NULL;
12301 }
12302
12303 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012304 n = syscall(SYS_getrandom,
12305 PyBytes_AS_STRING(bytes),
12306 PyBytes_GET_SIZE(bytes),
12307 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012308 if (n < 0 && errno == EINTR) {
12309 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012310 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012311 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012312
12313 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012314 continue;
12315 }
12316 break;
12317 }
12318
12319 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012320 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012321 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012322 }
12323
Victor Stinnerec2319c2016-09-20 23:00:59 +020012324 if (n != size) {
12325 _PyBytes_Resize(&bytes, n);
12326 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012327
12328 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012329
12330error:
12331 Py_DECREF(bytes);
12332 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012333}
12334#endif /* HAVE_GETRANDOM_SYSCALL */
12335
Larry Hastings31826802013-10-19 00:09:25 -070012336
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012337static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012338
12339 OS_STAT_METHODDEF
12340 OS_ACCESS_METHODDEF
12341 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012342 OS_CHDIR_METHODDEF
12343 OS_CHFLAGS_METHODDEF
12344 OS_CHMOD_METHODDEF
12345 OS_FCHMOD_METHODDEF
12346 OS_LCHMOD_METHODDEF
12347 OS_CHOWN_METHODDEF
12348 OS_FCHOWN_METHODDEF
12349 OS_LCHOWN_METHODDEF
12350 OS_LCHFLAGS_METHODDEF
12351 OS_CHROOT_METHODDEF
12352 OS_CTERMID_METHODDEF
12353 OS_GETCWD_METHODDEF
12354 OS_GETCWDB_METHODDEF
12355 OS_LINK_METHODDEF
12356 OS_LISTDIR_METHODDEF
12357 OS_LSTAT_METHODDEF
12358 OS_MKDIR_METHODDEF
12359 OS_NICE_METHODDEF
12360 OS_GETPRIORITY_METHODDEF
12361 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012362#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012363 {"readlink", (PyCFunction)posix_readlink,
12364 METH_VARARGS | METH_KEYWORDS,
12365 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012366#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012367#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012368 {"readlink", (PyCFunction)win_readlink,
12369 METH_VARARGS | METH_KEYWORDS,
12370 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012371#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012372 OS_RENAME_METHODDEF
12373 OS_REPLACE_METHODDEF
12374 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012375 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012376 OS_SYMLINK_METHODDEF
12377 OS_SYSTEM_METHODDEF
12378 OS_UMASK_METHODDEF
12379 OS_UNAME_METHODDEF
12380 OS_UNLINK_METHODDEF
12381 OS_REMOVE_METHODDEF
12382 OS_UTIME_METHODDEF
12383 OS_TIMES_METHODDEF
12384 OS__EXIT_METHODDEF
12385 OS_EXECV_METHODDEF
12386 OS_EXECVE_METHODDEF
12387 OS_SPAWNV_METHODDEF
12388 OS_SPAWNVE_METHODDEF
12389 OS_FORK1_METHODDEF
12390 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012391 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012392 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12393 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12394 OS_SCHED_GETPARAM_METHODDEF
12395 OS_SCHED_GETSCHEDULER_METHODDEF
12396 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12397 OS_SCHED_SETPARAM_METHODDEF
12398 OS_SCHED_SETSCHEDULER_METHODDEF
12399 OS_SCHED_YIELD_METHODDEF
12400 OS_SCHED_SETAFFINITY_METHODDEF
12401 OS_SCHED_GETAFFINITY_METHODDEF
12402 OS_OPENPTY_METHODDEF
12403 OS_FORKPTY_METHODDEF
12404 OS_GETEGID_METHODDEF
12405 OS_GETEUID_METHODDEF
12406 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012407#ifdef HAVE_GETGROUPLIST
12408 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12409#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012410 OS_GETGROUPS_METHODDEF
12411 OS_GETPID_METHODDEF
12412 OS_GETPGRP_METHODDEF
12413 OS_GETPPID_METHODDEF
12414 OS_GETUID_METHODDEF
12415 OS_GETLOGIN_METHODDEF
12416 OS_KILL_METHODDEF
12417 OS_KILLPG_METHODDEF
12418 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012419#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012420 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012421#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012422 OS_SETUID_METHODDEF
12423 OS_SETEUID_METHODDEF
12424 OS_SETREUID_METHODDEF
12425 OS_SETGID_METHODDEF
12426 OS_SETEGID_METHODDEF
12427 OS_SETREGID_METHODDEF
12428 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012429#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012430 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012431#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012432 OS_GETPGID_METHODDEF
12433 OS_SETPGRP_METHODDEF
12434 OS_WAIT_METHODDEF
12435 OS_WAIT3_METHODDEF
12436 OS_WAIT4_METHODDEF
12437 OS_WAITID_METHODDEF
12438 OS_WAITPID_METHODDEF
12439 OS_GETSID_METHODDEF
12440 OS_SETSID_METHODDEF
12441 OS_SETPGID_METHODDEF
12442 OS_TCGETPGRP_METHODDEF
12443 OS_TCSETPGRP_METHODDEF
12444 OS_OPEN_METHODDEF
12445 OS_CLOSE_METHODDEF
12446 OS_CLOSERANGE_METHODDEF
12447 OS_DEVICE_ENCODING_METHODDEF
12448 OS_DUP_METHODDEF
12449 OS_DUP2_METHODDEF
12450 OS_LOCKF_METHODDEF
12451 OS_LSEEK_METHODDEF
12452 OS_READ_METHODDEF
12453 OS_READV_METHODDEF
12454 OS_PREAD_METHODDEF
12455 OS_WRITE_METHODDEF
12456 OS_WRITEV_METHODDEF
12457 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012458#ifdef HAVE_SENDFILE
12459 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12460 posix_sendfile__doc__},
12461#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012462 OS_FSTAT_METHODDEF
12463 OS_ISATTY_METHODDEF
12464 OS_PIPE_METHODDEF
12465 OS_PIPE2_METHODDEF
12466 OS_MKFIFO_METHODDEF
12467 OS_MKNOD_METHODDEF
12468 OS_MAJOR_METHODDEF
12469 OS_MINOR_METHODDEF
12470 OS_MAKEDEV_METHODDEF
12471 OS_FTRUNCATE_METHODDEF
12472 OS_TRUNCATE_METHODDEF
12473 OS_POSIX_FALLOCATE_METHODDEF
12474 OS_POSIX_FADVISE_METHODDEF
12475 OS_PUTENV_METHODDEF
12476 OS_UNSETENV_METHODDEF
12477 OS_STRERROR_METHODDEF
12478 OS_FCHDIR_METHODDEF
12479 OS_FSYNC_METHODDEF
12480 OS_SYNC_METHODDEF
12481 OS_FDATASYNC_METHODDEF
12482 OS_WCOREDUMP_METHODDEF
12483 OS_WIFCONTINUED_METHODDEF
12484 OS_WIFSTOPPED_METHODDEF
12485 OS_WIFSIGNALED_METHODDEF
12486 OS_WIFEXITED_METHODDEF
12487 OS_WEXITSTATUS_METHODDEF
12488 OS_WTERMSIG_METHODDEF
12489 OS_WSTOPSIG_METHODDEF
12490 OS_FSTATVFS_METHODDEF
12491 OS_STATVFS_METHODDEF
12492 OS_CONFSTR_METHODDEF
12493 OS_SYSCONF_METHODDEF
12494 OS_FPATHCONF_METHODDEF
12495 OS_PATHCONF_METHODDEF
12496 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012497 OS__GETFULLPATHNAME_METHODDEF
12498 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012499 OS__GETDISKUSAGE_METHODDEF
12500 OS__GETFINALPATHNAME_METHODDEF
12501 OS__GETVOLUMEPATHNAME_METHODDEF
12502 OS_GETLOADAVG_METHODDEF
12503 OS_URANDOM_METHODDEF
12504 OS_SETRESUID_METHODDEF
12505 OS_SETRESGID_METHODDEF
12506 OS_GETRESUID_METHODDEF
12507 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012508
Larry Hastings2f936352014-08-05 14:04:04 +100012509 OS_GETXATTR_METHODDEF
12510 OS_SETXATTR_METHODDEF
12511 OS_REMOVEXATTR_METHODDEF
12512 OS_LISTXATTR_METHODDEF
12513
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012514#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12515 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12516#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012517 OS_CPU_COUNT_METHODDEF
12518 OS_GET_INHERITABLE_METHODDEF
12519 OS_SET_INHERITABLE_METHODDEF
12520 OS_GET_HANDLE_INHERITABLE_METHODDEF
12521 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012522#ifndef MS_WINDOWS
12523 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12524 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12525#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012526 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012527 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012528 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012529 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012530};
12531
12532
Brian Curtin52173d42010-12-02 18:29:18 +000012533#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012534static int
Brian Curtin52173d42010-12-02 18:29:18 +000012535enable_symlink()
12536{
12537 HANDLE tok;
12538 TOKEN_PRIVILEGES tok_priv;
12539 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012540
12541 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012542 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012543
12544 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012545 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012546
12547 tok_priv.PrivilegeCount = 1;
12548 tok_priv.Privileges[0].Luid = luid;
12549 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12550
12551 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12552 sizeof(TOKEN_PRIVILEGES),
12553 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012554 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012555
Brian Curtin3b4499c2010-12-28 14:31:47 +000012556 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12557 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012558}
12559#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12560
Barry Warsaw4a342091996-12-19 23:50:02 +000012561static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012563{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012564#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012565 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012566#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012567#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012568 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012569#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012570#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012571 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012572#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012573#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012575#endif
Fred Drakec9680921999-12-13 16:37:25 +000012576#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012577 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012578#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012579#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012580 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012581#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012582#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012583 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012584#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012585#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012586 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012587#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012588#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012589 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012590#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012591#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012592 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012593#endif
12594#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012595 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012596#endif
12597#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012599#endif
12600#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012601 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012602#endif
12603#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012604 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012605#endif
12606#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012607 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012608#endif
12609#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012611#endif
12612#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012614#endif
12615#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012616 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012617#endif
12618#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012620#endif
12621#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012622 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012623#endif
12624#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012626#endif
12627#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012629#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012630#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012631 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012632#endif
12633#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012635#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012636#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012637 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012638#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012639#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012640 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012641#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012642#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012643#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012645#endif
12646#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012648#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012649#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012650#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012651 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012652#endif
12653#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012654 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012655#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012656#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012657 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012658#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012659#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012660 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012661#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012662#ifdef O_TMPFILE
12663 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12664#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012665#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012666 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012667#endif
12668#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012669 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012670#endif
12671#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012673#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012674#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012676#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012677#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012679#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012680
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012681
Jesus Cea94363612012-06-22 18:32:07 +020012682#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012684#endif
12685#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012687#endif
12688
Tim Peters5aa91602002-01-30 05:46:57 +000012689/* MS Windows */
12690#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012691 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012693#endif
12694#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012695 /* Optimize for short life (keep in memory). */
12696 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012698#endif
12699#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012700 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012702#endif
12703#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012704 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012705 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012706#endif
12707#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012708 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012709 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012710#endif
12711
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012712/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012713#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012714 /* Send a SIGIO signal whenever input or output
12715 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012717#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012718#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012719 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012721#endif
12722#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012723 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012724 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012725#endif
12726#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012727 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012729#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012730#ifdef O_NOLINKS
12731 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012733#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012734#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012735 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012736 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012737#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012738
Victor Stinner8c62be82010-05-06 00:08:46 +000012739 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012740#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012742#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012743#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012745#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012746#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012748#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012749#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012751#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012752#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012754#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012755#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012757#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012758#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012760#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012761#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012763#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012764#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012766#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012767#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012769#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012770#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012772#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012773#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012775#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012776#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012777 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012778#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012779#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012781#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012782#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012783 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012784#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012785#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012786 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012787#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012788#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012789 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012790#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012791
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012792 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012793#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012795#endif /* ST_RDONLY */
12796#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012798#endif /* ST_NOSUID */
12799
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012800 /* GNU extensions */
12801#ifdef ST_NODEV
12802 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12803#endif /* ST_NODEV */
12804#ifdef ST_NOEXEC
12805 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12806#endif /* ST_NOEXEC */
12807#ifdef ST_SYNCHRONOUS
12808 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12809#endif /* ST_SYNCHRONOUS */
12810#ifdef ST_MANDLOCK
12811 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12812#endif /* ST_MANDLOCK */
12813#ifdef ST_WRITE
12814 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12815#endif /* ST_WRITE */
12816#ifdef ST_APPEND
12817 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12818#endif /* ST_APPEND */
12819#ifdef ST_NOATIME
12820 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12821#endif /* ST_NOATIME */
12822#ifdef ST_NODIRATIME
12823 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12824#endif /* ST_NODIRATIME */
12825#ifdef ST_RELATIME
12826 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12827#endif /* ST_RELATIME */
12828
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012829 /* FreeBSD sendfile() constants */
12830#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012831 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012832#endif
12833#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012834 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012835#endif
12836#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012837 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012838#endif
12839
Ross Lagerwall7807c352011-03-17 20:20:30 +020012840 /* constants for posix_fadvise */
12841#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012843#endif
12844#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012846#endif
12847#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012849#endif
12850#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012852#endif
12853#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012855#endif
12856#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012858#endif
12859
12860 /* constants for waitid */
12861#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012862 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12863 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12864 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012865#endif
12866#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012867 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012868#endif
12869#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012870 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012871#endif
12872#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012873 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012874#endif
12875#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012876 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012877#endif
12878#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012880#endif
12881#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012883#endif
12884#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012885 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012886#endif
12887
12888 /* constants for lockf */
12889#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012891#endif
12892#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012894#endif
12895#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012897#endif
12898#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012900#endif
12901
Guido van Rossum246bc171999-02-01 23:54:31 +000012902#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012903 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12904 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12905 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12906 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12907 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012908#endif
12909
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012910#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012911#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012912 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012913#endif
12914#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012915 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012916#endif
12917#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012918 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012919#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012920#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012922#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012923#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012924 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012925#endif
12926#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012928#endif
12929#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012930 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012931#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012932#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012934#endif
12935#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012937#endif
12938#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012939 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012940#endif
12941#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012942 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012943#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012944#endif
12945
Benjamin Peterson9428d532011-09-14 11:45:52 -040012946#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012947 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12948 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12949 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012950#endif
12951
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012952#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012953 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012954#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012955#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012956 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012957#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012958#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012959 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012960#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012961#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012962 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012963#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012964#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012965 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012966#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012967#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012968 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012969#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012970#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012971 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012972#endif
12973
Victor Stinner9b1f4742016-09-06 16:18:52 -070012974#ifdef HAVE_GETRANDOM_SYSCALL
12975 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12976 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12977#endif
12978
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012980}
12981
12982
Martin v. Löwis1a214512008-06-11 05:26:20 +000012983static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012984 PyModuleDef_HEAD_INIT,
12985 MODNAME,
12986 posix__doc__,
12987 -1,
12988 posix_methods,
12989 NULL,
12990 NULL,
12991 NULL,
12992 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012993};
12994
12995
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012996static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012997
12998#ifdef HAVE_FACCESSAT
12999 "HAVE_FACCESSAT",
13000#endif
13001
13002#ifdef HAVE_FCHDIR
13003 "HAVE_FCHDIR",
13004#endif
13005
13006#ifdef HAVE_FCHMOD
13007 "HAVE_FCHMOD",
13008#endif
13009
13010#ifdef HAVE_FCHMODAT
13011 "HAVE_FCHMODAT",
13012#endif
13013
13014#ifdef HAVE_FCHOWN
13015 "HAVE_FCHOWN",
13016#endif
13017
Larry Hastings00964ed2013-08-12 13:49:30 -040013018#ifdef HAVE_FCHOWNAT
13019 "HAVE_FCHOWNAT",
13020#endif
13021
Larry Hastings9cf065c2012-06-22 16:30:09 -070013022#ifdef HAVE_FEXECVE
13023 "HAVE_FEXECVE",
13024#endif
13025
13026#ifdef HAVE_FDOPENDIR
13027 "HAVE_FDOPENDIR",
13028#endif
13029
Georg Brandl306336b2012-06-24 12:55:33 +020013030#ifdef HAVE_FPATHCONF
13031 "HAVE_FPATHCONF",
13032#endif
13033
Larry Hastings9cf065c2012-06-22 16:30:09 -070013034#ifdef HAVE_FSTATAT
13035 "HAVE_FSTATAT",
13036#endif
13037
13038#ifdef HAVE_FSTATVFS
13039 "HAVE_FSTATVFS",
13040#endif
13041
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013042#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013043 "HAVE_FTRUNCATE",
13044#endif
13045
Larry Hastings9cf065c2012-06-22 16:30:09 -070013046#ifdef HAVE_FUTIMENS
13047 "HAVE_FUTIMENS",
13048#endif
13049
13050#ifdef HAVE_FUTIMES
13051 "HAVE_FUTIMES",
13052#endif
13053
13054#ifdef HAVE_FUTIMESAT
13055 "HAVE_FUTIMESAT",
13056#endif
13057
13058#ifdef HAVE_LINKAT
13059 "HAVE_LINKAT",
13060#endif
13061
13062#ifdef HAVE_LCHFLAGS
13063 "HAVE_LCHFLAGS",
13064#endif
13065
13066#ifdef HAVE_LCHMOD
13067 "HAVE_LCHMOD",
13068#endif
13069
13070#ifdef HAVE_LCHOWN
13071 "HAVE_LCHOWN",
13072#endif
13073
13074#ifdef HAVE_LSTAT
13075 "HAVE_LSTAT",
13076#endif
13077
13078#ifdef HAVE_LUTIMES
13079 "HAVE_LUTIMES",
13080#endif
13081
13082#ifdef HAVE_MKDIRAT
13083 "HAVE_MKDIRAT",
13084#endif
13085
13086#ifdef HAVE_MKFIFOAT
13087 "HAVE_MKFIFOAT",
13088#endif
13089
13090#ifdef HAVE_MKNODAT
13091 "HAVE_MKNODAT",
13092#endif
13093
13094#ifdef HAVE_OPENAT
13095 "HAVE_OPENAT",
13096#endif
13097
13098#ifdef HAVE_READLINKAT
13099 "HAVE_READLINKAT",
13100#endif
13101
13102#ifdef HAVE_RENAMEAT
13103 "HAVE_RENAMEAT",
13104#endif
13105
13106#ifdef HAVE_SYMLINKAT
13107 "HAVE_SYMLINKAT",
13108#endif
13109
13110#ifdef HAVE_UNLINKAT
13111 "HAVE_UNLINKAT",
13112#endif
13113
13114#ifdef HAVE_UTIMENSAT
13115 "HAVE_UTIMENSAT",
13116#endif
13117
13118#ifdef MS_WINDOWS
13119 "MS_WINDOWS",
13120#endif
13121
13122 NULL
13123};
13124
13125
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013126PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013127INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013128{
Victor Stinner8c62be82010-05-06 00:08:46 +000013129 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013130 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013131 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013132
Brian Curtin52173d42010-12-02 18:29:18 +000013133#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013134 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013135#endif
13136
Victor Stinner8c62be82010-05-06 00:08:46 +000013137 m = PyModule_Create(&posixmodule);
13138 if (m == NULL)
13139 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013140
Victor Stinner8c62be82010-05-06 00:08:46 +000013141 /* Initialize environ dictionary */
13142 v = convertenviron();
13143 Py_XINCREF(v);
13144 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13145 return NULL;
13146 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013147
Victor Stinner8c62be82010-05-06 00:08:46 +000013148 if (all_ins(m))
13149 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013150
Victor Stinner8c62be82010-05-06 00:08:46 +000013151 if (setup_confname_tables(m))
13152 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013153
Victor Stinner8c62be82010-05-06 00:08:46 +000013154 Py_INCREF(PyExc_OSError);
13155 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013156
Guido van Rossumb3d39562000-01-31 18:41:26 +000013157#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013158 if (posix_putenv_garbage == NULL)
13159 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013160#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013161
Victor Stinner8c62be82010-05-06 00:08:46 +000013162 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013163#if defined(HAVE_WAITID) && !defined(__APPLE__)
13164 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013165 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13166 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013167#endif
13168
Christian Heimes25827622013-10-12 01:27:08 +020013169 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013170 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13171 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13172 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013173 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13174 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013175 structseq_new = StatResultType.tp_new;
13176 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013177
Christian Heimes25827622013-10-12 01:27:08 +020013178 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013179 if (PyStructSequence_InitType2(&StatVFSResultType,
13180 &statvfs_result_desc) < 0)
13181 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013182#ifdef NEED_TICKS_PER_SECOND
13183# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013184 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013185# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013186 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013187# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013188 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013189# endif
13190#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013191
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013192#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013193 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013194 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13195 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013196 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013197#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013198
13199 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013200 if (PyStructSequence_InitType2(&TerminalSizeType,
13201 &TerminalSize_desc) < 0)
13202 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013203
13204 /* initialize scandir types */
13205 if (PyType_Ready(&ScandirIteratorType) < 0)
13206 return NULL;
13207 if (PyType_Ready(&DirEntryType) < 0)
13208 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013209 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013210#if defined(HAVE_WAITID) && !defined(__APPLE__)
13211 Py_INCREF((PyObject*) &WaitidResultType);
13212 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13213#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013214 Py_INCREF((PyObject*) &StatResultType);
13215 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13216 Py_INCREF((PyObject*) &StatVFSResultType);
13217 PyModule_AddObject(m, "statvfs_result",
13218 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013219
13220#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013221 Py_INCREF(&SchedParamType);
13222 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013223#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013224
Larry Hastings605a62d2012-06-24 04:33:36 -070013225 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013226 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13227 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013228 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13229
13230 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013231 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13232 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013233 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13234
Thomas Wouters477c8d52006-05-27 19:21:47 +000013235#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013236 /*
13237 * Step 2 of weak-linking support on Mac OS X.
13238 *
13239 * The code below removes functions that are not available on the
13240 * currently active platform.
13241 *
13242 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013243 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013244 * OSX 10.4.
13245 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013246#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013247 if (fstatvfs == NULL) {
13248 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13249 return NULL;
13250 }
13251 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013252#endif /* HAVE_FSTATVFS */
13253
13254#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013255 if (statvfs == NULL) {
13256 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13257 return NULL;
13258 }
13259 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013260#endif /* HAVE_STATVFS */
13261
13262# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013263 if (lchown == NULL) {
13264 if (PyObject_DelAttrString(m, "lchown") == -1) {
13265 return NULL;
13266 }
13267 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013268#endif /* HAVE_LCHOWN */
13269
13270
13271#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013272
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013273 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013274 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13275
Larry Hastings6fe20b32012-04-19 15:07:49 -070013276 billion = PyLong_FromLong(1000000000);
13277 if (!billion)
13278 return NULL;
13279
Larry Hastings9cf065c2012-06-22 16:30:09 -070013280 /* suppress "function not used" warnings */
13281 {
13282 int ignored;
13283 fd_specified("", -1);
13284 follow_symlinks_specified("", 1);
13285 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13286 dir_fd_converter(Py_None, &ignored);
13287 dir_fd_unavailable(Py_None, &ignored);
13288 }
13289
13290 /*
13291 * provide list of locally available functions
13292 * so os.py can populate support_* lists
13293 */
13294 list = PyList_New(0);
13295 if (!list)
13296 return NULL;
13297 for (trace = have_functions; *trace; trace++) {
13298 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13299 if (!unicode)
13300 return NULL;
13301 if (PyList_Append(list, unicode))
13302 return NULL;
13303 Py_DECREF(unicode);
13304 }
13305 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013306
13307 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013308 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013309
13310 initialized = 1;
13311
Victor Stinner8c62be82010-05-06 00:08:46 +000013312 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013313}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013314
13315#ifdef __cplusplus
13316}
13317#endif