blob: f4a21679d0b20271162a5455d581226f93bb5014 [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{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700468 if (func == NULL) /* nothing to register? do nothing. */
469 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200470 if (*lst == NULL) {
471 *lst = PyList_New(0);
472 if (*lst == NULL)
473 return -1;
474 }
475 return PyList_Append(*lst, func);
476}
477#endif
478
479/* Legacy wrapper */
480void
481PyOS_AfterFork(void)
482{
483#ifdef HAVE_FORK
484 PyOS_AfterFork_Child();
485#endif
486}
487
488
Victor Stinner6036e442015-03-08 01:58:04 +0100489#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200490/* defined in fileutils.c */
491PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
492PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
493 ULONG, struct _Py_stat_struct *);
494#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700495
496#ifdef MS_WINDOWS
497static int
498win32_warn_bytes_api()
499{
500 return PyErr_WarnEx(PyExc_DeprecationWarning,
501 "The Windows bytes API has been deprecated, "
502 "use Unicode filenames instead",
503 1);
504}
505#endif
506
507
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508#ifndef MS_WINDOWS
509PyObject *
510_PyLong_FromUid(uid_t uid)
511{
512 if (uid == (uid_t)-1)
513 return PyLong_FromLong(-1);
514 return PyLong_FromUnsignedLong(uid);
515}
516
517PyObject *
518_PyLong_FromGid(gid_t gid)
519{
520 if (gid == (gid_t)-1)
521 return PyLong_FromLong(-1);
522 return PyLong_FromUnsignedLong(gid);
523}
524
525int
526_Py_Uid_Converter(PyObject *obj, void *p)
527{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 uid_t uid;
529 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200530 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700532 unsigned long uresult;
533
534 index = PyNumber_Index(obj);
535 if (index == NULL) {
536 PyErr_Format(PyExc_TypeError,
537 "uid should be integer, not %.200s",
538 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200539 return 0;
540 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700541
542 /*
543 * Handling uid_t is complicated for two reasons:
544 * * Although uid_t is (always?) unsigned, it still
545 * accepts -1.
546 * * We don't know its size in advance--it may be
547 * bigger than an int, or it may be smaller than
548 * a long.
549 *
550 * So a bit of defensive programming is in order.
551 * Start with interpreting the value passed
552 * in as a signed long and see if it works.
553 */
554
555 result = PyLong_AsLongAndOverflow(index, &overflow);
556
557 if (!overflow) {
558 uid = (uid_t)result;
559
560 if (result == -1) {
561 if (PyErr_Occurred())
562 goto fail;
563 /* It's a legitimate -1, we're done. */
564 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566
567 /* Any other negative number is disallowed. */
568 if (result < 0)
569 goto underflow;
570
571 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200572 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700573 (long)uid != result)
574 goto underflow;
575 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200576 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700577
578 if (overflow < 0)
579 goto underflow;
580
581 /*
582 * Okay, the value overflowed a signed long. If it
583 * fits in an *unsigned* long, it may still be okay,
584 * as uid_t may be unsigned long on this platform.
585 */
586 uresult = PyLong_AsUnsignedLong(index);
587 if (PyErr_Occurred()) {
588 if (PyErr_ExceptionMatches(PyExc_OverflowError))
589 goto overflow;
590 goto fail;
591 }
592
593 uid = (uid_t)uresult;
594
595 /*
596 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
597 * but this value would get interpreted as (uid_t)-1 by chown
598 * and its siblings. That's not what the user meant! So we
599 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100600 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700601 */
602 if (uid == (uid_t)-1)
603 goto overflow;
604
605 /* Ensure the value wasn't truncated. */
606 if (sizeof(uid_t) < sizeof(long) &&
607 (unsigned long)uid != uresult)
608 goto overflow;
609 /* fallthrough */
610
611success:
612 Py_DECREF(index);
613 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 return 1;
615
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618 "uid is less than minimum");
619 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700621overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623 "uid is greater than maximum");
624 /* fallthrough */
625
626fail:
627 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 return 0;
629}
630
631int
632_Py_Gid_Converter(PyObject *obj, void *p)
633{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634 gid_t gid;
635 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200637 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700638 unsigned long uresult;
639
640 index = PyNumber_Index(obj);
641 if (index == NULL) {
642 PyErr_Format(PyExc_TypeError,
643 "gid should be integer, not %.200s",
644 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200645 return 0;
646 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647
648 /*
649 * Handling gid_t is complicated for two reasons:
650 * * Although gid_t is (always?) unsigned, it still
651 * accepts -1.
652 * * We don't know its size in advance--it may be
653 * bigger than an int, or it may be smaller than
654 * a long.
655 *
656 * So a bit of defensive programming is in order.
657 * Start with interpreting the value passed
658 * in as a signed long and see if it works.
659 */
660
661 result = PyLong_AsLongAndOverflow(index, &overflow);
662
663 if (!overflow) {
664 gid = (gid_t)result;
665
666 if (result == -1) {
667 if (PyErr_Occurred())
668 goto fail;
669 /* It's a legitimate -1, we're done. */
670 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672
673 /* Any other negative number is disallowed. */
674 if (result < 0) {
675 goto underflow;
676 }
677
678 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 (long)gid != result)
681 goto underflow;
682 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 if (overflow < 0)
686 goto underflow;
687
688 /*
689 * Okay, the value overflowed a signed long. If it
690 * fits in an *unsigned* long, it may still be okay,
691 * as gid_t may be unsigned long on this platform.
692 */
693 uresult = PyLong_AsUnsignedLong(index);
694 if (PyErr_Occurred()) {
695 if (PyErr_ExceptionMatches(PyExc_OverflowError))
696 goto overflow;
697 goto fail;
698 }
699
700 gid = (gid_t)uresult;
701
702 /*
703 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
704 * but this value would get interpreted as (gid_t)-1 by chown
705 * and its siblings. That's not what the user meant! So we
706 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100707 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700708 */
709 if (gid == (gid_t)-1)
710 goto overflow;
711
712 /* Ensure the value wasn't truncated. */
713 if (sizeof(gid_t) < sizeof(long) &&
714 (unsigned long)gid != uresult)
715 goto overflow;
716 /* fallthrough */
717
718success:
719 Py_DECREF(index);
720 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 return 1;
722
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700725 "gid is less than minimum");
726 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700728overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730 "gid is greater than maximum");
731 /* fallthrough */
732
733fail:
734 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200735 return 0;
736}
737#endif /* MS_WINDOWS */
738
739
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700740#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800741
742
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
744static int
745_Py_Dev_Converter(PyObject *obj, void *p)
746{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200747 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200748 if (PyErr_Occurred())
749 return 0;
750 return 1;
751}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800752#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200753
754
Larry Hastings9cf065c2012-06-22 16:30:09 -0700755#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400756/*
757 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
758 * without the int cast, the value gets interpreted as uint (4291925331),
759 * which doesn't play nicely with all the initializer lines in this file that
760 * look like this:
761 * int dir_fd = DEFAULT_DIR_FD;
762 */
763#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700764#else
765#define DEFAULT_DIR_FD (-100)
766#endif
767
768static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300769_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200770{
771 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 long long_value;
773
774 PyObject *index = PyNumber_Index(o);
775 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 return 0;
777 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300779 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780 long_value = PyLong_AsLongAndOverflow(index, &overflow);
781 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300782 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200783 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 return 0;
787 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200788 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700790 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700791 return 0;
792 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793
Larry Hastings9cf065c2012-06-22 16:30:09 -0700794 *p = (int)long_value;
795 return 1;
796}
797
798static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200799dir_fd_converter(PyObject *o, void *p)
800{
801 if (o == Py_None) {
802 *(int *)p = DEFAULT_DIR_FD;
803 return 1;
804 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300805 else if (PyIndex_Check(o)) {
806 return _fd_converter(o, (int *)p);
807 }
808 else {
809 PyErr_Format(PyExc_TypeError,
810 "argument should be integer or None, not %.200s",
811 Py_TYPE(o)->tp_name);
812 return 0;
813 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700814}
815
816
Larry Hastings9cf065c2012-06-22 16:30:09 -0700817/*
818 * A PyArg_ParseTuple "converter" function
819 * that handles filesystem paths in the manner
820 * preferred by the os module.
821 *
822 * path_converter accepts (Unicode) strings and their
823 * subclasses, and bytes and their subclasses. What
824 * it does with the argument depends on the platform:
825 *
826 * * On Windows, if we get a (Unicode) string we
827 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700828 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700829 *
830 * * On all other platforms, strings are encoded
831 * to bytes using PyUnicode_FSConverter, then we
832 * extract the char * from the bytes object and
833 * return that.
834 *
835 * path_converter also optionally accepts signed
836 * integers (representing open file descriptors) instead
837 * of path strings.
838 *
839 * Input fields:
840 * path.nullable
841 * If nonzero, the path is permitted to be None.
842 * path.allow_fd
843 * If nonzero, the path is permitted to be a file handle
844 * (a signed int) instead of a string.
845 * path.function_name
846 * If non-NULL, path_converter will use that as the name
847 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700848 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700849 * path.argument_name
850 * If non-NULL, path_converter will use that as the name
851 * of the parameter in error messages.
852 * (If path.argument_name is NULL it uses "path".)
853 *
854 * Output fields:
855 * path.wide
856 * Points to the path if it was expressed as Unicode
857 * and was not encoded. (Only used on Windows.)
858 * path.narrow
859 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700860 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000861 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700862 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700863 * path.fd
864 * Contains a file descriptor if path.accept_fd was true
865 * and the caller provided a signed integer instead of any
866 * sort of string.
867 *
868 * WARNING: if your "path" parameter is optional, and is
869 * unspecified, path_converter will never get called.
870 * So if you set allow_fd, you *MUST* initialize path.fd = -1
871 * yourself!
872 * path.length
873 * The length of the path in characters, if specified as
874 * a string.
875 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800876 * The original object passed in (if get a PathLike object,
877 * the result of PyOS_FSPath() is treated as the original object).
878 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700879 * path.cleanup
880 * For internal use only. May point to a temporary object.
881 * (Pay no attention to the man behind the curtain.)
882 *
883 * At most one of path.wide or path.narrow will be non-NULL.
884 * If path was None and path.nullable was set,
885 * or if path was an integer and path.allow_fd was set,
886 * both path.wide and path.narrow will be NULL
887 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200888 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700889 * path_converter takes care to not write to the path_t
890 * unless it's successful. However it must reset the
891 * "cleanup" field each time it's called.
892 *
893 * Use as follows:
894 * path_t path;
895 * memset(&path, 0, sizeof(path));
896 * PyArg_ParseTuple(args, "O&", path_converter, &path);
897 * // ... use values from path ...
898 * path_cleanup(&path);
899 *
900 * (Note that if PyArg_Parse fails you don't need to call
901 * path_cleanup(). However it is safe to do so.)
902 */
903typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100904 const char *function_name;
905 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700906 int nullable;
907 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300908 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700909#ifdef MS_WINDOWS
910 BOOL narrow;
911#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300912 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700913#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700914 int fd;
915 Py_ssize_t length;
916 PyObject *object;
917 PyObject *cleanup;
918} path_t;
919
Steve Dowercc16be82016-09-08 10:35:16 -0700920#ifdef MS_WINDOWS
921#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
922 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
923#else
Larry Hastings2f936352014-08-05 14:04:04 +1000924#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
925 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700926#endif
Larry Hastings31826802013-10-19 00:09:25 -0700927
Larry Hastings9cf065c2012-06-22 16:30:09 -0700928static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800929path_cleanup(path_t *path)
930{
931 Py_CLEAR(path->object);
932 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933}
934
935static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300936path_converter(PyObject *o, void *p)
937{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700938 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800939 PyObject *bytes = NULL;
940 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700941 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300942 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700943#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800944 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700945 const wchar_t *wide;
946#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700947
948#define FORMAT_EXCEPTION(exc, fmt) \
949 PyErr_Format(exc, "%s%s" fmt, \
950 path->function_name ? path->function_name : "", \
951 path->function_name ? ": " : "", \
952 path->argument_name ? path->argument_name : "path")
953
954 /* Py_CLEANUP_SUPPORTED support */
955 if (o == NULL) {
956 path_cleanup(path);
957 return 1;
958 }
959
Brett Cannon3f9183b2016-08-26 14:44:48 -0700960 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800961 path->object = path->cleanup = NULL;
962 /* path->object owns a reference to the original object */
963 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300965 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700967#ifdef MS_WINDOWS
968 path->narrow = FALSE;
969#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700970 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700971#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700972 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800973 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700974 }
975
Brett Cannon3f9183b2016-08-26 14:44:48 -0700976 /* Only call this here so that we don't treat the return value of
977 os.fspath() as an fd or buffer. */
978 is_index = path->allow_fd && PyIndex_Check(o);
979 is_buffer = PyObject_CheckBuffer(o);
980 is_bytes = PyBytes_Check(o);
981 is_unicode = PyUnicode_Check(o);
982
983 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
984 /* Inline PyOS_FSPath() for better error messages. */
985 _Py_IDENTIFIER(__fspath__);
986 PyObject *func = NULL;
987
988 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
989 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800990 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700991 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800992 /* still owns a reference to the original object */
993 Py_DECREF(o);
994 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700995 Py_DECREF(func);
996 if (NULL == o) {
997 goto error_exit;
998 }
999 else if (PyUnicode_Check(o)) {
1000 is_unicode = 1;
1001 }
1002 else if (PyBytes_Check(o)) {
1003 is_bytes = 1;
1004 }
1005 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001006 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001007 }
1008 }
1009
1010 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001012 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001013 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 }
Victor Stinner59799a82013-11-13 14:17:30 +01001016 if (length > 32767) {
1017 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001019 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001020 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001021 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001022 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001023 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001024
1025 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001026 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001028 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001029#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001030 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001031 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001032 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001033#endif
1034 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001035 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001036 bytes = o;
1037 Py_INCREF(bytes);
1038 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001039 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001040 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1041 "%s%s%s should be %s, not %.200s",
1042 path->function_name ? path->function_name : "",
1043 path->function_name ? ": " : "",
1044 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001045 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1046 "integer or None" :
1047 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1048 path->nullable ? "string, bytes, os.PathLike or None" :
1049 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001050 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001052 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001053 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001055 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001056 }
1057 }
Steve Dowercc16be82016-09-08 10:35:16 -07001058 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001059 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001060 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001061 }
1062 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001063#ifdef MS_WINDOWS
1064 path->narrow = FALSE;
1065#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001066 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001067#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001068 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001069 }
1070 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001071 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001072 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1073 path->function_name ? path->function_name : "",
1074 path->function_name ? ": " : "",
1075 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001076 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1077 "integer or None" :
1078 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1079 path->nullable ? "string, bytes, os.PathLike or None" :
1080 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001081 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001082 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 }
1084
Larry Hastings9cf065c2012-06-22 16:30:09 -07001085 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001087 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001088 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001089 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 }
1091
Steve Dowercc16be82016-09-08 10:35:16 -07001092#ifdef MS_WINDOWS
1093 wo = PyUnicode_DecodeFSDefaultAndSize(
1094 narrow,
1095 length
1096 );
1097 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001098 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001099 }
1100
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001102 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001104 }
1105 if (length > 32767) {
1106 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001108 }
1109 if (wcslen(wide) != length) {
1110 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001111 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001112 }
1113 path->wide = wide;
1114 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001115 path->cleanup = wo;
1116 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001117#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001118 path->wide = NULL;
1119 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001120 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001121 /* Still a reference owned by path->object, don't have to
1122 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001123 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001124 }
1125 else {
1126 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001127 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001128#endif
1129 path->fd = -1;
1130
1131 success_exit:
1132 path->length = length;
1133 path->object = o;
1134 return Py_CLEANUP_SUPPORTED;
1135
1136 error_exit:
1137 Py_XDECREF(o);
1138 Py_XDECREF(bytes);
1139#ifdef MS_WINDOWS
1140 Py_XDECREF(wo);
1141#endif
1142 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143}
1144
1145static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001146argument_unavailable_error(const char *function_name, const char *argument_name)
1147{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001148 PyErr_Format(PyExc_NotImplementedError,
1149 "%s%s%s unavailable on this platform",
1150 (function_name != NULL) ? function_name : "",
1151 (function_name != NULL) ? ": ": "",
1152 argument_name);
1153}
1154
1155static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001156dir_fd_unavailable(PyObject *o, void *p)
1157{
1158 int dir_fd;
1159 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001160 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001161 if (dir_fd != DEFAULT_DIR_FD) {
1162 argument_unavailable_error(NULL, "dir_fd");
1163 return 0;
1164 }
1165 *(int *)p = dir_fd;
1166 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001167}
1168
1169static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001170fd_specified(const char *function_name, int fd)
1171{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001172 if (fd == -1)
1173 return 0;
1174
1175 argument_unavailable_error(function_name, "fd");
1176 return 1;
1177}
1178
1179static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001180follow_symlinks_specified(const char *function_name, int follow_symlinks)
1181{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001182 if (follow_symlinks)
1183 return 0;
1184
1185 argument_unavailable_error(function_name, "follow_symlinks");
1186 return 1;
1187}
1188
1189static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001190path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1191{
Steve Dowercc16be82016-09-08 10:35:16 -07001192 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1193#ifndef MS_WINDOWS
1194 && !path->narrow
1195#endif
1196 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001197 PyErr_Format(PyExc_ValueError,
1198 "%s: can't specify dir_fd without matching path",
1199 function_name);
1200 return 1;
1201 }
1202 return 0;
1203}
1204
1205static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001206dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1207{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001208 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1209 PyErr_Format(PyExc_ValueError,
1210 "%s: can't specify both dir_fd and fd",
1211 function_name);
1212 return 1;
1213 }
1214 return 0;
1215}
1216
1217static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001218fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1219 int follow_symlinks)
1220{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001221 if ((fd > 0) && (!follow_symlinks)) {
1222 PyErr_Format(PyExc_ValueError,
1223 "%s: cannot use fd and follow_symlinks together",
1224 function_name);
1225 return 1;
1226 }
1227 return 0;
1228}
1229
1230static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001231dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1232 int follow_symlinks)
1233{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001234 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1235 PyErr_Format(PyExc_ValueError,
1236 "%s: cannot use dir_fd and follow_symlinks together",
1237 function_name);
1238 return 1;
1239 }
1240 return 0;
1241}
1242
Larry Hastings2f936352014-08-05 14:04:04 +10001243#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001244 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001245#else
Larry Hastings2f936352014-08-05 14:04:04 +10001246 typedef off_t Py_off_t;
1247#endif
1248
1249static int
1250Py_off_t_converter(PyObject *arg, void *addr)
1251{
1252#ifdef HAVE_LARGEFILE_SUPPORT
1253 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1254#else
1255 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001256#endif
1257 if (PyErr_Occurred())
1258 return 0;
1259 return 1;
1260}
Larry Hastings2f936352014-08-05 14:04:04 +10001261
1262static PyObject *
1263PyLong_FromPy_off_t(Py_off_t offset)
1264{
1265#ifdef HAVE_LARGEFILE_SUPPORT
1266 return PyLong_FromLongLong(offset);
1267#else
1268 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001269#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001270}
1271
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001272#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273
1274static int
Brian Curtind25aef52011-06-13 15:16:04 -05001275win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276{
Martin Panter70214ad2016-08-04 02:38:59 +00001277 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1278 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001279 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001280
1281 if (0 == DeviceIoControl(
1282 reparse_point_handle,
1283 FSCTL_GET_REPARSE_POINT,
1284 NULL, 0, /* in buffer */
1285 target_buffer, sizeof(target_buffer),
1286 &n_bytes_returned,
1287 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001288 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001289
1290 if (reparse_tag)
1291 *reparse_tag = rdb->ReparseTag;
1292
Brian Curtind25aef52011-06-13 15:16:04 -05001293 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001294}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001295
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001296#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001297
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001299#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001300/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001301** environ directly, we must obtain it with _NSGetEnviron(). See also
1302** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001303*/
1304#include <crt_externs.h>
1305static char **environ;
1306#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001308#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309
Barry Warsaw53699e91996-12-10 23:23:01 +00001310static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001311convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312{
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001314#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001315 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001316#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001318#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001319
Victor Stinner8c62be82010-05-06 00:08:46 +00001320 d = PyDict_New();
1321 if (d == NULL)
1322 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001323#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 if (environ == NULL)
1325 environ = *_NSGetEnviron();
1326#endif
1327#ifdef MS_WINDOWS
1328 /* _wenviron must be initialized in this way if the program is started
1329 through main() instead of wmain(). */
1330 _wgetenv(L"");
1331 if (_wenviron == NULL)
1332 return d;
1333 /* This part ignores errors */
1334 for (e = _wenviron; *e != NULL; e++) {
1335 PyObject *k;
1336 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001337 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001338 if (p == NULL)
1339 continue;
1340 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1341 if (k == NULL) {
1342 PyErr_Clear();
1343 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001344 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1346 if (v == NULL) {
1347 PyErr_Clear();
1348 Py_DECREF(k);
1349 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001350 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 if (PyDict_GetItem(d, k) == NULL) {
1352 if (PyDict_SetItem(d, k, v) != 0)
1353 PyErr_Clear();
1354 }
1355 Py_DECREF(k);
1356 Py_DECREF(v);
1357 }
1358#else
1359 if (environ == NULL)
1360 return d;
1361 /* This part ignores errors */
1362 for (e = environ; *e != NULL; e++) {
1363 PyObject *k;
1364 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001365 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 if (p == NULL)
1367 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001368 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 if (k == NULL) {
1370 PyErr_Clear();
1371 continue;
1372 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001373 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 if (v == NULL) {
1375 PyErr_Clear();
1376 Py_DECREF(k);
1377 continue;
1378 }
1379 if (PyDict_GetItem(d, k) == NULL) {
1380 if (PyDict_SetItem(d, k, v) != 0)
1381 PyErr_Clear();
1382 }
1383 Py_DECREF(k);
1384 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001385 }
1386#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001387 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388}
1389
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390/* Set a POSIX-specific error from errno, and return NULL */
1391
Barry Warsawd58d7641998-07-23 16:14:40 +00001392static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001393posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001394{
Victor Stinner8c62be82010-05-06 00:08:46 +00001395 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001396}
Mark Hammondef8b6542001-05-13 08:04:26 +00001397
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001398#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001399static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001400win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001401{
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 /* XXX We should pass the function name along in the future.
1403 (winreg.c also wants to pass the function name.)
1404 This would however require an additional param to the
1405 Windows error object, which is non-trivial.
1406 */
1407 errno = GetLastError();
1408 if (filename)
1409 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1410 else
1411 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001412}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001413
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001414static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001415win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001416{
1417 /* XXX - see win32_error for comments on 'function' */
1418 errno = GetLastError();
1419 if (filename)
1420 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001421 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001422 errno,
1423 filename);
1424 else
1425 return PyErr_SetFromWindowsErr(errno);
1426}
1427
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001428#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001429
Larry Hastings9cf065c2012-06-22 16:30:09 -07001430static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001431path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432{
1433#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001434 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1435 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001437 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001438#endif
1439}
1440
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001441static PyObject *
1442path_object_error2(PyObject *path, PyObject *path2)
1443{
1444#ifdef MS_WINDOWS
1445 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1446 PyExc_OSError, 0, path, path2);
1447#else
1448 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1449#endif
1450}
1451
1452static PyObject *
1453path_error(path_t *path)
1454{
1455 return path_object_error(path->object);
1456}
Larry Hastings31826802013-10-19 00:09:25 -07001457
Larry Hastingsb0827312014-02-09 22:05:19 -08001458static PyObject *
1459path_error2(path_t *path, path_t *path2)
1460{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001461 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001462}
1463
1464
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001465/* POSIX generic methods */
1466
Larry Hastings2f936352014-08-05 14:04:04 +10001467static int
1468fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001469{
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001471 int *pointer = (int *)p;
1472 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001474 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001475 *pointer = fd;
1476 return 1;
1477}
1478
1479static PyObject *
1480posix_fildes_fd(int fd, int (*func)(int))
1481{
1482 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001483 int async_err = 0;
1484
1485 do {
1486 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001487 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001488 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001489 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001490 Py_END_ALLOW_THREADS
1491 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1492 if (res != 0)
1493 return (!async_err) ? posix_error() : NULL;
1494 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001495}
Guido van Rossum21142a01999-01-08 21:05:37 +00001496
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001497
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001498#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499/* This is a reimplementation of the C library's chdir function,
1500 but one that produces Win32 errors instead of DOS error codes.
1501 chdir is essentially a wrapper around SetCurrentDirectory; however,
1502 it also needs to set "magic" environment variables indicating
1503 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001504static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505win32_wchdir(LPCWSTR path)
1506{
Victor Stinnered537822015-12-13 21:40:26 +01001507 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 int result;
1509 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 if(!SetCurrentDirectoryW(path))
1512 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001513 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 if (!result)
1515 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001516 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001517 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 if (!new_path) {
1519 SetLastError(ERROR_OUTOFMEMORY);
1520 return FALSE;
1521 }
1522 result = GetCurrentDirectoryW(result, new_path);
1523 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001524 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001525 return FALSE;
1526 }
1527 }
1528 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1529 wcsncmp(new_path, L"//", 2) == 0)
1530 /* UNC path, nothing to do. */
1531 return TRUE;
1532 env[1] = new_path[0];
1533 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001534 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001535 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001536 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001537}
1538#endif
1539
Martin v. Löwis14694662006-02-03 12:54:16 +00001540#ifdef MS_WINDOWS
1541/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1542 - time stamps are restricted to second resolution
1543 - file modification times suffer from forth-and-back conversions between
1544 UTC and local time
1545 Therefore, we implement our own stat, based on the Win32 API directly.
1546*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001547#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001548#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001549
Victor Stinner6036e442015-03-08 01:58:04 +01001550static void
Steve Dowercc16be82016-09-08 10:35:16 -07001551find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1552 BY_HANDLE_FILE_INFORMATION *info,
1553 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001554{
1555 memset(info, 0, sizeof(*info));
1556 info->dwFileAttributes = pFileData->dwFileAttributes;
1557 info->ftCreationTime = pFileData->ftCreationTime;
1558 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1559 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1560 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1561 info->nFileSizeLow = pFileData->nFileSizeLow;
1562/* info->nNumberOfLinks = 1; */
1563 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1564 *reparse_tag = pFileData->dwReserved0;
1565 else
1566 *reparse_tag = 0;
1567}
1568
Guido van Rossumd8faa362007-04-27 19:54:29 +00001569static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001570attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001571{
Victor Stinner8c62be82010-05-06 00:08:46 +00001572 HANDLE hFindFile;
1573 WIN32_FIND_DATAW FileData;
1574 hFindFile = FindFirstFileW(pszFile, &FileData);
1575 if (hFindFile == INVALID_HANDLE_VALUE)
1576 return FALSE;
1577 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001578 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001580}
1581
Brian Curtind25aef52011-06-13 15:16:04 -05001582static BOOL
1583get_target_path(HANDLE hdl, wchar_t **target_path)
1584{
1585 int buf_size, result_length;
1586 wchar_t *buf;
1587
1588 /* We have a good handle to the target, use it to determine
1589 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001590 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1591 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001592 if(!buf_size)
1593 return FALSE;
1594
Victor Stinnerc36674a2016-03-16 14:30:16 +01001595 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001596 if (!buf) {
1597 SetLastError(ERROR_OUTOFMEMORY);
1598 return FALSE;
1599 }
1600
Steve Dower2ea51c92015-03-20 21:49:12 -07001601 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001602 buf, buf_size, VOLUME_NAME_DOS);
1603
1604 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001605 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001606 return FALSE;
1607 }
1608
1609 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001610 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001611 return FALSE;
1612 }
1613
1614 buf[result_length] = 0;
1615
1616 *target_path = buf;
1617 return TRUE;
1618}
1619
1620static int
Steve Dowercc16be82016-09-08 10:35:16 -07001621win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001622 BOOL traverse)
1623{
Victor Stinner26de69d2011-06-17 15:15:38 +02001624 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001625 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001628 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001629 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001630
Steve Dowercc16be82016-09-08 10:35:16 -07001631 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001633 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001634 0, /* share mode */
1635 NULL, /* security attributes */
1636 OPEN_EXISTING,
1637 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001638 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1639 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001640 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001641 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1642 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001643 NULL);
1644
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001645 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001646 /* Either the target doesn't exist, or we don't have access to
1647 get a handle to it. If the former, we need to return an error.
1648 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001649 DWORD lastError = GetLastError();
1650 if (lastError != ERROR_ACCESS_DENIED &&
1651 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001652 return -1;
1653 /* Could not get attributes on open file. Fall back to
1654 reading the directory. */
1655 if (!attributes_from_dir(path, &info, &reparse_tag))
1656 /* Very strange. This should not fail now */
1657 return -1;
1658 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1659 if (traverse) {
1660 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001661 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001662 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001664 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 } else {
1666 if (!GetFileInformationByHandle(hFile, &info)) {
1667 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001668 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 }
1670 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001671 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1672 return -1;
1673
1674 /* Close the outer open file handle now that we're about to
1675 reopen it with different flags. */
1676 if (!CloseHandle(hFile))
1677 return -1;
1678
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001680 /* In order to call GetFinalPathNameByHandle we need to open
1681 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001682 hFile2 = CreateFileW(
1683 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1684 NULL, OPEN_EXISTING,
1685 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1686 NULL);
1687 if (hFile2 == INVALID_HANDLE_VALUE)
1688 return -1;
1689
1690 if (!get_target_path(hFile2, &target_path))
1691 return -1;
1692
Steve Dowercc16be82016-09-08 10:35:16 -07001693 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001694 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001695 return code;
1696 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001697 } else
1698 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001699 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001700 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701
1702 /* Set S_IEXEC if it is an .exe, .bat, ... */
1703 dot = wcsrchr(path, '.');
1704 if (dot) {
1705 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1706 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1707 result->st_mode |= 0111;
1708 }
1709 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710}
1711
1712static int
Steve Dowercc16be82016-09-08 10:35:16 -07001713win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001714{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001715 /* Protocol violation: we explicitly clear errno, instead of
1716 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001717 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 errno = 0;
1719 return code;
1720}
Brian Curtind25aef52011-06-13 15:16:04 -05001721/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001722
1723 In Posix, stat automatically traverses symlinks and returns the stat
1724 structure for the target. In Windows, the equivalent GetFileAttributes by
1725 default does not traverse symlinks and instead returns attributes for
1726 the symlink.
1727
1728 Therefore, win32_lstat will get the attributes traditionally, and
1729 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001730 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001731
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001732static int
Steve Dowercc16be82016-09-08 10:35:16 -07001733win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001734{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001735 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001736}
1737
Victor Stinner8c62be82010-05-06 00:08:46 +00001738static int
Steve Dowercc16be82016-09-08 10:35:16 -07001739win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001740{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001741 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001742}
1743
Martin v. Löwis14694662006-02-03 12:54:16 +00001744#endif /* MS_WINDOWS */
1745
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001746PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001747"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001748This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001749 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1751\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001752Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1753or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001755See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756
1757static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 {"st_mode", "protection bits"},
1759 {"st_ino", "inode"},
1760 {"st_dev", "device"},
1761 {"st_nlink", "number of hard links"},
1762 {"st_uid", "user ID of owner"},
1763 {"st_gid", "group ID of owner"},
1764 {"st_size", "total size, in bytes"},
1765 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1766 {NULL, "integer time of last access"},
1767 {NULL, "integer time of last modification"},
1768 {NULL, "integer time of last change"},
1769 {"st_atime", "time of last access"},
1770 {"st_mtime", "time of last modification"},
1771 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001772 {"st_atime_ns", "time of last access in nanoseconds"},
1773 {"st_mtime_ns", "time of last modification in nanoseconds"},
1774 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001775#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001778#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001781#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001784#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001786#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001787#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001789#endif
1790#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001792#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001793#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1794 {"st_file_attributes", "Windows file attribute bits"},
1795#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797};
1798
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001799#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001800#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001801#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001802#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001803#endif
1804
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001805#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1807#else
1808#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1809#endif
1810
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001811#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1813#else
1814#define ST_RDEV_IDX ST_BLOCKS_IDX
1815#endif
1816
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001817#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1818#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1819#else
1820#define ST_FLAGS_IDX ST_RDEV_IDX
1821#endif
1822
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001823#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001824#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001825#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001826#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001827#endif
1828
1829#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1830#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1831#else
1832#define ST_BIRTHTIME_IDX ST_GEN_IDX
1833#endif
1834
Zachary Ware63f277b2014-06-19 09:46:37 -05001835#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1836#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1837#else
1838#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1839#endif
1840
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 "stat_result", /* name */
1843 stat_result__doc__, /* doc */
1844 stat_result_fields,
1845 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001846};
1847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1850This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001851 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001852or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001854See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001855
1856static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 {"f_bsize", },
1858 {"f_frsize", },
1859 {"f_blocks", },
1860 {"f_bfree", },
1861 {"f_bavail", },
1862 {"f_files", },
1863 {"f_ffree", },
1864 {"f_favail", },
1865 {"f_flag", },
1866 {"f_namemax",},
1867 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868};
1869
1870static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 "statvfs_result", /* name */
1872 statvfs_result__doc__, /* doc */
1873 statvfs_result_fields,
1874 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001875};
1876
Ross Lagerwall7807c352011-03-17 20:20:30 +02001877#if defined(HAVE_WAITID) && !defined(__APPLE__)
1878PyDoc_STRVAR(waitid_result__doc__,
1879"waitid_result: Result from waitid.\n\n\
1880This object may be accessed either as a tuple of\n\
1881 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1882or via the attributes si_pid, si_uid, and so on.\n\
1883\n\
1884See os.waitid for more information.");
1885
1886static PyStructSequence_Field waitid_result_fields[] = {
1887 {"si_pid", },
1888 {"si_uid", },
1889 {"si_signo", },
1890 {"si_status", },
1891 {"si_code", },
1892 {0}
1893};
1894
1895static PyStructSequence_Desc waitid_result_desc = {
1896 "waitid_result", /* name */
1897 waitid_result__doc__, /* doc */
1898 waitid_result_fields,
1899 5
1900};
1901static PyTypeObject WaitidResultType;
1902#endif
1903
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001904static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001905static PyTypeObject StatResultType;
1906static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001907#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001908static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001909#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001910static newfunc structseq_new;
1911
1912static PyObject *
1913statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1914{
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 PyStructSequence *result;
1916 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001917
Victor Stinner8c62be82010-05-06 00:08:46 +00001918 result = (PyStructSequence*)structseq_new(type, args, kwds);
1919 if (!result)
1920 return NULL;
1921 /* If we have been initialized from a tuple,
1922 st_?time might be set to None. Initialize it
1923 from the int slots. */
1924 for (i = 7; i <= 9; i++) {
1925 if (result->ob_item[i+3] == Py_None) {
1926 Py_DECREF(Py_None);
1927 Py_INCREF(result->ob_item[i]);
1928 result->ob_item[i+3] = result->ob_item[i];
1929 }
1930 }
1931 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001932}
1933
1934
1935
1936/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001937static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001938
1939PyDoc_STRVAR(stat_float_times__doc__,
1940"stat_float_times([newval]) -> oldval\n\n\
1941Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001942\n\
1943If value is True, future calls to stat() return floats; if it is False,\n\
1944future calls return ints.\n\
1945If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001946
Larry Hastings2f936352014-08-05 14:04:04 +10001947/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001948static PyObject*
1949stat_float_times(PyObject* self, PyObject *args)
1950{
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 int newval = -1;
1952 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1953 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001954 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1955 "stat_float_times() is deprecated",
1956 1))
1957 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 if (newval == -1)
1959 /* Return old value */
1960 return PyBool_FromLong(_stat_float_times);
1961 _stat_float_times = newval;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001962 Py_RETURN_NONE;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001963}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001964
Larry Hastings6fe20b32012-04-19 15:07:49 -07001965static PyObject *billion = NULL;
1966
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001967static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001968fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001969{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001970 PyObject *s = _PyLong_FromTime_t(sec);
1971 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1972 PyObject *s_in_ns = NULL;
1973 PyObject *ns_total = NULL;
1974 PyObject *float_s = NULL;
1975
1976 if (!(s && ns_fractional))
1977 goto exit;
1978
1979 s_in_ns = PyNumber_Multiply(s, billion);
1980 if (!s_in_ns)
1981 goto exit;
1982
1983 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1984 if (!ns_total)
1985 goto exit;
1986
Victor Stinner4195b5c2012-02-08 23:03:19 +01001987 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001988 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1989 if (!float_s)
1990 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001992 else {
1993 float_s = s;
1994 Py_INCREF(float_s);
1995 }
1996
1997 PyStructSequence_SET_ITEM(v, index, s);
1998 PyStructSequence_SET_ITEM(v, index+3, float_s);
1999 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2000 s = NULL;
2001 float_s = NULL;
2002 ns_total = NULL;
2003exit:
2004 Py_XDECREF(s);
2005 Py_XDECREF(ns_fractional);
2006 Py_XDECREF(s_in_ns);
2007 Py_XDECREF(ns_total);
2008 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002009}
2010
Tim Peters5aa91602002-01-30 05:46:57 +00002011/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002012 (used by posix_stat() and posix_fstat()) */
2013static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002014_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002015{
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 unsigned long ansec, mnsec, cnsec;
2017 PyObject *v = PyStructSequence_New(&StatResultType);
2018 if (v == NULL)
2019 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002020
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002022 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002023 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002024#ifdef MS_WINDOWS
2025 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002026#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002027 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002028#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002030#if defined(MS_WINDOWS)
2031 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2032 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2033#else
2034 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2035 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2036#endif
xdegaye50e86032017-05-22 11:15:08 +02002037 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2038 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002039
Martin v. Löwis14694662006-02-03 12:54:16 +00002040#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 ansec = st->st_atim.tv_nsec;
2042 mnsec = st->st_mtim.tv_nsec;
2043 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002044#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 ansec = st->st_atimespec.tv_nsec;
2046 mnsec = st->st_mtimespec.tv_nsec;
2047 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002048#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 ansec = st->st_atime_nsec;
2050 mnsec = st->st_mtime_nsec;
2051 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002052#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002055 fill_time(v, 7, st->st_atime, ansec);
2056 fill_time(v, 8, st->st_mtime, mnsec);
2057 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002058
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002059#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2061 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002062#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002063#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2065 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002066#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002067#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002068 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2069 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002070#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002071#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2073 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002074#endif
2075#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002077 PyObject *val;
2078 unsigned long bsec,bnsec;
2079 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002080#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002081 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002082#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002083 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002084#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002085 if (_stat_float_times) {
2086 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2087 } else {
2088 val = PyLong_FromLong((long)bsec);
2089 }
2090 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2091 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002093#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002094#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2096 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002097#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002098#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2099 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2100 PyLong_FromUnsignedLong(st->st_file_attributes));
2101#endif
Fred Drake699f3522000-06-29 21:12:41 +00002102
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 if (PyErr_Occurred()) {
2104 Py_DECREF(v);
2105 return NULL;
2106 }
Fred Drake699f3522000-06-29 21:12:41 +00002107
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002109}
2110
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002111/* POSIX methods */
2112
Guido van Rossum94f6f721999-01-06 18:42:14 +00002113
2114static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002115posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002116 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002117{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002118 STRUCT_STAT st;
2119 int result;
2120
2121#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2122 if (follow_symlinks_specified(function_name, follow_symlinks))
2123 return NULL;
2124#endif
2125
2126 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2127 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2128 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2129 return NULL;
2130
2131 Py_BEGIN_ALLOW_THREADS
2132 if (path->fd != -1)
2133 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002134#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002135 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002136 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002137 else
Steve Dowercc16be82016-09-08 10:35:16 -07002138 result = win32_lstat(path->wide, &st);
2139#else
2140 else
2141#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002142 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2143 result = LSTAT(path->narrow, &st);
2144 else
Steve Dowercc16be82016-09-08 10:35:16 -07002145#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002146#ifdef HAVE_FSTATAT
2147 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2148 result = fstatat(dir_fd, path->narrow, &st,
2149 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2150 else
Steve Dowercc16be82016-09-08 10:35:16 -07002151#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002152 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002153#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002154 Py_END_ALLOW_THREADS
2155
Victor Stinner292c8352012-10-30 02:17:38 +01002156 if (result != 0) {
2157 return path_error(path);
2158 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002159
2160 return _pystat_fromstructstat(&st);
2161}
2162
Larry Hastings2f936352014-08-05 14:04:04 +10002163/*[python input]
2164
2165for s in """
2166
2167FACCESSAT
2168FCHMODAT
2169FCHOWNAT
2170FSTATAT
2171LINKAT
2172MKDIRAT
2173MKFIFOAT
2174MKNODAT
2175OPENAT
2176READLINKAT
2177SYMLINKAT
2178UNLINKAT
2179
2180""".strip().split():
2181 s = s.strip()
2182 print("""
2183#ifdef HAVE_{s}
2184 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002185#else
Larry Hastings2f936352014-08-05 14:04:04 +10002186 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002187#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002188""".rstrip().format(s=s))
2189
2190for s in """
2191
2192FCHDIR
2193FCHMOD
2194FCHOWN
2195FDOPENDIR
2196FEXECVE
2197FPATHCONF
2198FSTATVFS
2199FTRUNCATE
2200
2201""".strip().split():
2202 s = s.strip()
2203 print("""
2204#ifdef HAVE_{s}
2205 #define PATH_HAVE_{s} 1
2206#else
2207 #define PATH_HAVE_{s} 0
2208#endif
2209
2210""".rstrip().format(s=s))
2211[python start generated code]*/
2212
2213#ifdef HAVE_FACCESSAT
2214 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2215#else
2216 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2217#endif
2218
2219#ifdef HAVE_FCHMODAT
2220 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2221#else
2222 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2223#endif
2224
2225#ifdef HAVE_FCHOWNAT
2226 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2227#else
2228 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2229#endif
2230
2231#ifdef HAVE_FSTATAT
2232 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2233#else
2234 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2235#endif
2236
2237#ifdef HAVE_LINKAT
2238 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2239#else
2240 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2241#endif
2242
2243#ifdef HAVE_MKDIRAT
2244 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2245#else
2246 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2247#endif
2248
2249#ifdef HAVE_MKFIFOAT
2250 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2251#else
2252 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2253#endif
2254
2255#ifdef HAVE_MKNODAT
2256 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2257#else
2258 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2259#endif
2260
2261#ifdef HAVE_OPENAT
2262 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2263#else
2264 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2265#endif
2266
2267#ifdef HAVE_READLINKAT
2268 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2269#else
2270 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2271#endif
2272
2273#ifdef HAVE_SYMLINKAT
2274 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2275#else
2276 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2277#endif
2278
2279#ifdef HAVE_UNLINKAT
2280 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2281#else
2282 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2283#endif
2284
2285#ifdef HAVE_FCHDIR
2286 #define PATH_HAVE_FCHDIR 1
2287#else
2288 #define PATH_HAVE_FCHDIR 0
2289#endif
2290
2291#ifdef HAVE_FCHMOD
2292 #define PATH_HAVE_FCHMOD 1
2293#else
2294 #define PATH_HAVE_FCHMOD 0
2295#endif
2296
2297#ifdef HAVE_FCHOWN
2298 #define PATH_HAVE_FCHOWN 1
2299#else
2300 #define PATH_HAVE_FCHOWN 0
2301#endif
2302
2303#ifdef HAVE_FDOPENDIR
2304 #define PATH_HAVE_FDOPENDIR 1
2305#else
2306 #define PATH_HAVE_FDOPENDIR 0
2307#endif
2308
2309#ifdef HAVE_FEXECVE
2310 #define PATH_HAVE_FEXECVE 1
2311#else
2312 #define PATH_HAVE_FEXECVE 0
2313#endif
2314
2315#ifdef HAVE_FPATHCONF
2316 #define PATH_HAVE_FPATHCONF 1
2317#else
2318 #define PATH_HAVE_FPATHCONF 0
2319#endif
2320
2321#ifdef HAVE_FSTATVFS
2322 #define PATH_HAVE_FSTATVFS 1
2323#else
2324 #define PATH_HAVE_FSTATVFS 0
2325#endif
2326
2327#ifdef HAVE_FTRUNCATE
2328 #define PATH_HAVE_FTRUNCATE 1
2329#else
2330 #define PATH_HAVE_FTRUNCATE 0
2331#endif
2332/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002333
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002334#ifdef MS_WINDOWS
2335 #undef PATH_HAVE_FTRUNCATE
2336 #define PATH_HAVE_FTRUNCATE 1
2337#endif
Larry Hastings31826802013-10-19 00:09:25 -07002338
Larry Hastings61272b72014-01-07 12:41:53 -08002339/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002340
2341class path_t_converter(CConverter):
2342
2343 type = "path_t"
2344 impl_by_reference = True
2345 parse_by_reference = True
2346
2347 converter = 'path_converter'
2348
2349 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002350 # right now path_t doesn't support default values.
2351 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002352 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002353 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002354
Larry Hastings2f936352014-08-05 14:04:04 +10002355 if self.c_default not in (None, 'Py_None'):
2356 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002357
2358 self.nullable = nullable
2359 self.allow_fd = allow_fd
2360
Larry Hastings7726ac92014-01-31 22:03:12 -08002361 def pre_render(self):
2362 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002363 if isinstance(value, str):
2364 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002365 return str(int(bool(value)))
2366
2367 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002368 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002369 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002370 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002371 strify(self.nullable),
2372 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002373 )
2374
2375 def cleanup(self):
2376 return "path_cleanup(&" + self.name + ");\n"
2377
2378
2379class dir_fd_converter(CConverter):
2380 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002381
Larry Hastings2f936352014-08-05 14:04:04 +10002382 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002383 if self.default in (unspecified, None):
2384 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002385 if isinstance(requires, str):
2386 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2387 else:
2388 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002389
Larry Hastings2f936352014-08-05 14:04:04 +10002390class fildes_converter(CConverter):
2391 type = 'int'
2392 converter = 'fildes_converter'
2393
2394class uid_t_converter(CConverter):
2395 type = "uid_t"
2396 converter = '_Py_Uid_Converter'
2397
2398class gid_t_converter(CConverter):
2399 type = "gid_t"
2400 converter = '_Py_Gid_Converter'
2401
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002402class dev_t_converter(CConverter):
2403 type = 'dev_t'
2404 converter = '_Py_Dev_Converter'
2405
2406class dev_t_return_converter(unsigned_long_return_converter):
2407 type = 'dev_t'
2408 conversion_fn = '_PyLong_FromDev'
2409 unsigned_cast = '(dev_t)'
2410
Larry Hastings2f936352014-08-05 14:04:04 +10002411class FSConverter_converter(CConverter):
2412 type = 'PyObject *'
2413 converter = 'PyUnicode_FSConverter'
2414 def converter_init(self):
2415 if self.default is not unspecified:
2416 fail("FSConverter_converter does not support default values")
2417 self.c_default = 'NULL'
2418
2419 def cleanup(self):
2420 return "Py_XDECREF(" + self.name + ");\n"
2421
2422class pid_t_converter(CConverter):
2423 type = 'pid_t'
2424 format_unit = '" _Py_PARSE_PID "'
2425
2426class idtype_t_converter(int_converter):
2427 type = 'idtype_t'
2428
2429class id_t_converter(CConverter):
2430 type = 'id_t'
2431 format_unit = '" _Py_PARSE_PID "'
2432
Benjamin Petersonca470632016-09-06 13:47:26 -07002433class intptr_t_converter(CConverter):
2434 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002435 format_unit = '" _Py_PARSE_INTPTR "'
2436
2437class Py_off_t_converter(CConverter):
2438 type = 'Py_off_t'
2439 converter = 'Py_off_t_converter'
2440
2441class Py_off_t_return_converter(long_return_converter):
2442 type = 'Py_off_t'
2443 conversion_fn = 'PyLong_FromPy_off_t'
2444
2445class path_confname_converter(CConverter):
2446 type="int"
2447 converter="conv_path_confname"
2448
2449class confstr_confname_converter(path_confname_converter):
2450 converter='conv_confstr_confname'
2451
2452class sysconf_confname_converter(path_confname_converter):
2453 converter="conv_sysconf_confname"
2454
2455class sched_param_converter(CConverter):
2456 type = 'struct sched_param'
2457 converter = 'convert_sched_param'
2458 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002459
Larry Hastings61272b72014-01-07 12:41:53 -08002460[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002461/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002462
Larry Hastings61272b72014-01-07 12:41:53 -08002463/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002464
Larry Hastings2a727912014-01-16 11:32:01 -08002465os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002466
2467 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002468 Path to be examined; can be string, bytes, path-like object or
2469 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002470
2471 *
2472
Larry Hastings2f936352014-08-05 14:04:04 +10002473 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002474 If not None, it should be a file descriptor open to a directory,
2475 and path should be a relative string; path will then be relative to
2476 that directory.
2477
2478 follow_symlinks: bool = True
2479 If False, and the last element of the path is a symbolic link,
2480 stat will examine the symbolic link itself instead of the file
2481 the link points to.
2482
2483Perform a stat system call on the given path.
2484
2485dir_fd and follow_symlinks may not be implemented
2486 on your platform. If they are unavailable, using them will raise a
2487 NotImplementedError.
2488
2489It's an error to use dir_fd or follow_symlinks when specifying path as
2490 an open file descriptor.
2491
Larry Hastings61272b72014-01-07 12:41:53 -08002492[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002493
Larry Hastings31826802013-10-19 00:09:25 -07002494static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002495os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002496/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002497{
2498 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2499}
2500
Larry Hastings2f936352014-08-05 14:04:04 +10002501
2502/*[clinic input]
2503os.lstat
2504
2505 path : path_t
2506
2507 *
2508
2509 dir_fd : dir_fd(requires='fstatat') = None
2510
2511Perform a stat system call on the given path, without following symbolic links.
2512
2513Like stat(), but do not follow symbolic links.
2514Equivalent to stat(path, follow_symlinks=False).
2515[clinic start generated code]*/
2516
Larry Hastings2f936352014-08-05 14:04:04 +10002517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002518os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2519/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002520{
2521 int follow_symlinks = 0;
2522 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2523}
Larry Hastings31826802013-10-19 00:09:25 -07002524
Larry Hastings2f936352014-08-05 14:04:04 +10002525
Larry Hastings61272b72014-01-07 12:41:53 -08002526/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002527os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002528
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002529 path: path_t
2530 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002531
2532 mode: int
2533 Operating-system mode bitfield. Can be F_OK to test existence,
2534 or the inclusive-OR of R_OK, W_OK, and X_OK.
2535
2536 *
2537
Larry Hastings2f936352014-08-05 14:04:04 +10002538 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002539 If not None, it should be a file descriptor open to a directory,
2540 and path should be relative; path will then be relative to that
2541 directory.
2542
2543 effective_ids: bool = False
2544 If True, access will use the effective uid/gid instead of
2545 the real uid/gid.
2546
2547 follow_symlinks: bool = True
2548 If False, and the last element of the path is a symbolic link,
2549 access will examine the symbolic link itself instead of the file
2550 the link points to.
2551
2552Use the real uid/gid to test for access to a path.
2553
2554{parameters}
2555dir_fd, effective_ids, and follow_symlinks may not be implemented
2556 on your platform. If they are unavailable, using them will raise a
2557 NotImplementedError.
2558
2559Note that most operations will use the effective uid/gid, therefore this
2560 routine can be used in a suid/sgid environment to test if the invoking user
2561 has the specified access to the path.
2562
Larry Hastings61272b72014-01-07 12:41:53 -08002563[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002564
Larry Hastings2f936352014-08-05 14:04:04 +10002565static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002566os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002567 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002568/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002569{
Larry Hastings2f936352014-08-05 14:04:04 +10002570 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002571
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002572#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002574#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002576#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002577
Larry Hastings9cf065c2012-06-22 16:30:09 -07002578#ifndef HAVE_FACCESSAT
2579 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002580 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002581
2582 if (effective_ids) {
2583 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002584 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002585 }
2586#endif
2587
2588#ifdef MS_WINDOWS
2589 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002590 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591 Py_END_ALLOW_THREADS
2592
2593 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002594 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002595 * * we didn't get a -1, and
2596 * * write access wasn't requested,
2597 * * or the file isn't read-only,
2598 * * or it's a directory.
2599 * (Directories cannot be read-only on Windows.)
2600 */
Larry Hastings2f936352014-08-05 14:04:04 +10002601 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002602 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002604 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605#else
2606
2607 Py_BEGIN_ALLOW_THREADS
2608#ifdef HAVE_FACCESSAT
2609 if ((dir_fd != DEFAULT_DIR_FD) ||
2610 effective_ids ||
2611 !follow_symlinks) {
2612 int flags = 0;
2613 if (!follow_symlinks)
2614 flags |= AT_SYMLINK_NOFOLLOW;
2615 if (effective_ids)
2616 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002617 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002618 }
2619 else
2620#endif
Larry Hastings31826802013-10-19 00:09:25 -07002621 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002623 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624#endif
2625
Larry Hastings9cf065c2012-06-22 16:30:09 -07002626 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002627}
2628
Guido van Rossumd371ff11999-01-25 16:12:23 +00002629#ifndef F_OK
2630#define F_OK 0
2631#endif
2632#ifndef R_OK
2633#define R_OK 4
2634#endif
2635#ifndef W_OK
2636#define W_OK 2
2637#endif
2638#ifndef X_OK
2639#define X_OK 1
2640#endif
2641
Larry Hastings31826802013-10-19 00:09:25 -07002642
Guido van Rossumd371ff11999-01-25 16:12:23 +00002643#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002644/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002645os.ttyname -> DecodeFSDefault
2646
2647 fd: int
2648 Integer file descriptor handle.
2649
2650 /
2651
2652Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002653[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002654
Larry Hastings31826802013-10-19 00:09:25 -07002655static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002656os_ttyname_impl(PyObject *module, int fd)
2657/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002658{
2659 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002660
Larry Hastings31826802013-10-19 00:09:25 -07002661 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002662 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002663 posix_error();
2664 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002666#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002667
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002668#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002669/*[clinic input]
2670os.ctermid
2671
2672Return the name of the controlling terminal for this process.
2673[clinic start generated code]*/
2674
Larry Hastings2f936352014-08-05 14:04:04 +10002675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002676os_ctermid_impl(PyObject *module)
2677/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002678{
Victor Stinner8c62be82010-05-06 00:08:46 +00002679 char *ret;
2680 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002681
Greg Wardb48bc172000-03-01 21:51:56 +00002682#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002686#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002687 if (ret == NULL)
2688 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002689 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002690}
Larry Hastings2f936352014-08-05 14:04:04 +10002691#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002692
Larry Hastings2f936352014-08-05 14:04:04 +10002693
2694/*[clinic input]
2695os.chdir
2696
2697 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2698
2699Change the current working directory to the specified path.
2700
2701path may always be specified as a string.
2702On some platforms, path may also be specified as an open file descriptor.
2703 If this functionality is unavailable, using it raises an exception.
2704[clinic start generated code]*/
2705
Larry Hastings2f936352014-08-05 14:04:04 +10002706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002707os_chdir_impl(PyObject *module, path_t *path)
2708/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002709{
2710 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711
2712 Py_BEGIN_ALLOW_THREADS
2713#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002714 /* on unix, success = 0, on windows, success = !0 */
2715 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716#else
2717#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002718 if (path->fd != -1)
2719 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002720 else
2721#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002722 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723#endif
2724 Py_END_ALLOW_THREADS
2725
2726 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002727 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002728 }
2729
Larry Hastings2f936352014-08-05 14:04:04 +10002730 Py_RETURN_NONE;
2731}
2732
2733
2734#ifdef HAVE_FCHDIR
2735/*[clinic input]
2736os.fchdir
2737
2738 fd: fildes
2739
2740Change to the directory of the given file descriptor.
2741
2742fd must be opened on a directory, not a file.
2743Equivalent to os.chdir(fd).
2744
2745[clinic start generated code]*/
2746
Fred Drake4d1e64b2002-04-15 19:40:07 +00002747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002748os_fchdir_impl(PyObject *module, int fd)
2749/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002750{
Larry Hastings2f936352014-08-05 14:04:04 +10002751 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002752}
2753#endif /* HAVE_FCHDIR */
2754
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002755
Larry Hastings2f936352014-08-05 14:04:04 +10002756/*[clinic input]
2757os.chmod
2758
2759 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2760 Path to be modified. May always be specified as a str or bytes.
2761 On some platforms, path may also be specified as an open file descriptor.
2762 If this functionality is unavailable, using it raises an exception.
2763
2764 mode: int
2765 Operating-system mode bitfield.
2766
2767 *
2768
2769 dir_fd : dir_fd(requires='fchmodat') = None
2770 If not None, it should be a file descriptor open to a directory,
2771 and path should be relative; path will then be relative to that
2772 directory.
2773
2774 follow_symlinks: bool = True
2775 If False, and the last element of the path is a symbolic link,
2776 chmod will modify the symbolic link itself instead of the file
2777 the link points to.
2778
2779Change the access permissions of a file.
2780
2781It is an error to use dir_fd or follow_symlinks when specifying path as
2782 an open file descriptor.
2783dir_fd and follow_symlinks may not be implemented on your platform.
2784 If they are unavailable, using them will raise a NotImplementedError.
2785
2786[clinic start generated code]*/
2787
Larry Hastings2f936352014-08-05 14:04:04 +10002788static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002789os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002790 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002791/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002792{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002795#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002798
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799#ifdef HAVE_FCHMODAT
2800 int fchmodat_nofollow_unsupported = 0;
2801#endif
2802
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2804 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002805 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002806#endif
2807
2808#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002810 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002811 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 result = 0;
2813 else {
2814 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002815 attr &= ~FILE_ATTRIBUTE_READONLY;
2816 else
2817 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002818 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 }
2820 Py_END_ALLOW_THREADS
2821
2822 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002823 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 }
2825#else /* MS_WINDOWS */
2826 Py_BEGIN_ALLOW_THREADS
2827#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002828 if (path->fd != -1)
2829 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830 else
2831#endif
2832#ifdef HAVE_LCHMOD
2833 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002834 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 else
2836#endif
2837#ifdef HAVE_FCHMODAT
2838 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2839 /*
2840 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2841 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002842 * and then says it isn't implemented yet.
2843 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 *
2845 * Once it is supported, os.chmod will automatically
2846 * support dir_fd and follow_symlinks=False. (Hopefully.)
2847 * Until then, we need to be careful what exception we raise.
2848 */
Larry Hastings2f936352014-08-05 14:04:04 +10002849 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2851 /*
2852 * But wait! We can't throw the exception without allowing threads,
2853 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2854 */
2855 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002856 result &&
2857 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2858 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 }
2860 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002861#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002862 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002863 Py_END_ALLOW_THREADS
2864
2865 if (result) {
2866#ifdef HAVE_FCHMODAT
2867 if (fchmodat_nofollow_unsupported) {
2868 if (dir_fd != DEFAULT_DIR_FD)
2869 dir_fd_and_follow_symlinks_invalid("chmod",
2870 dir_fd, follow_symlinks);
2871 else
2872 follow_symlinks_specified("chmod", follow_symlinks);
2873 }
2874 else
2875#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002876 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002877 }
2878#endif
2879
Larry Hastings2f936352014-08-05 14:04:04 +10002880 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002881}
2882
Larry Hastings9cf065c2012-06-22 16:30:09 -07002883
Christian Heimes4e30a842007-11-30 22:12:06 +00002884#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002885/*[clinic input]
2886os.fchmod
2887
2888 fd: int
2889 mode: int
2890
2891Change the access permissions of the file given by file descriptor fd.
2892
2893Equivalent to os.chmod(fd, mode).
2894[clinic start generated code]*/
2895
Larry Hastings2f936352014-08-05 14:04:04 +10002896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002897os_fchmod_impl(PyObject *module, int fd, int mode)
2898/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002899{
2900 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002901 int async_err = 0;
2902
2903 do {
2904 Py_BEGIN_ALLOW_THREADS
2905 res = fchmod(fd, mode);
2906 Py_END_ALLOW_THREADS
2907 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2908 if (res != 0)
2909 return (!async_err) ? posix_error() : NULL;
2910
Victor Stinner8c62be82010-05-06 00:08:46 +00002911 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002912}
2913#endif /* HAVE_FCHMOD */
2914
Larry Hastings2f936352014-08-05 14:04:04 +10002915
Christian Heimes4e30a842007-11-30 22:12:06 +00002916#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002917/*[clinic input]
2918os.lchmod
2919
2920 path: path_t
2921 mode: int
2922
2923Change the access permissions of a file, without following symbolic links.
2924
2925If path is a symlink, this affects the link itself rather than the target.
2926Equivalent to chmod(path, mode, follow_symlinks=False)."
2927[clinic start generated code]*/
2928
Larry Hastings2f936352014-08-05 14:04:04 +10002929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002930os_lchmod_impl(PyObject *module, path_t *path, int mode)
2931/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002932{
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002935 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002937 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002938 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002939 return NULL;
2940 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002942}
2943#endif /* HAVE_LCHMOD */
2944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002945
Thomas Wouterscf297e42007-02-23 15:07:44 +00002946#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002947/*[clinic input]
2948os.chflags
2949
2950 path: path_t
2951 flags: unsigned_long(bitwise=True)
2952 follow_symlinks: bool=True
2953
2954Set file flags.
2955
2956If follow_symlinks is False, and the last element of the path is a symbolic
2957 link, chflags will change flags on the symbolic link itself instead of the
2958 file the link points to.
2959follow_symlinks may not be implemented on your platform. If it is
2960unavailable, using it will raise a NotImplementedError.
2961
2962[clinic start generated code]*/
2963
Larry Hastings2f936352014-08-05 14:04:04 +10002964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002965os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002966 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002967/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002968{
2969 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002970
2971#ifndef HAVE_LCHFLAGS
2972 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002973 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002974#endif
2975
Victor Stinner8c62be82010-05-06 00:08:46 +00002976 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977#ifdef HAVE_LCHFLAGS
2978 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002979 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980 else
2981#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002982 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984
Larry Hastings2f936352014-08-05 14:04:04 +10002985 if (result)
2986 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987
Larry Hastings2f936352014-08-05 14:04:04 +10002988 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002989}
2990#endif /* HAVE_CHFLAGS */
2991
Larry Hastings2f936352014-08-05 14:04:04 +10002992
Thomas Wouterscf297e42007-02-23 15:07:44 +00002993#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002994/*[clinic input]
2995os.lchflags
2996
2997 path: path_t
2998 flags: unsigned_long(bitwise=True)
2999
3000Set file flags.
3001
3002This function will not follow symbolic links.
3003Equivalent to chflags(path, flags, follow_symlinks=False).
3004[clinic start generated code]*/
3005
Larry Hastings2f936352014-08-05 14:04:04 +10003006static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003007os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3008/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003009{
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003012 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003014 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003015 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003016 }
Victor Stinner292c8352012-10-30 02:17:38 +01003017 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003018}
3019#endif /* HAVE_LCHFLAGS */
3020
Larry Hastings2f936352014-08-05 14:04:04 +10003021
Martin v. Löwis244edc82001-10-04 22:44:26 +00003022#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003023/*[clinic input]
3024os.chroot
3025 path: path_t
3026
3027Change root directory to path.
3028
3029[clinic start generated code]*/
3030
Larry Hastings2f936352014-08-05 14:04:04 +10003031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003032os_chroot_impl(PyObject *module, path_t *path)
3033/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003034{
3035 int res;
3036 Py_BEGIN_ALLOW_THREADS
3037 res = chroot(path->narrow);
3038 Py_END_ALLOW_THREADS
3039 if (res < 0)
3040 return path_error(path);
3041 Py_RETURN_NONE;
3042}
3043#endif /* HAVE_CHROOT */
3044
Martin v. Löwis244edc82001-10-04 22:44:26 +00003045
Guido van Rossum21142a01999-01-08 21:05:37 +00003046#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003047/*[clinic input]
3048os.fsync
3049
3050 fd: fildes
3051
3052Force write of fd to disk.
3053[clinic start generated code]*/
3054
Larry Hastings2f936352014-08-05 14:04:04 +10003055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003056os_fsync_impl(PyObject *module, int fd)
3057/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003058{
3059 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003060}
3061#endif /* HAVE_FSYNC */
3062
Larry Hastings2f936352014-08-05 14:04:04 +10003063
Ross Lagerwall7807c352011-03-17 20:20:30 +02003064#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003065/*[clinic input]
3066os.sync
3067
3068Force write of everything to disk.
3069[clinic start generated code]*/
3070
Larry Hastings2f936352014-08-05 14:04:04 +10003071static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003072os_sync_impl(PyObject *module)
3073/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003074{
3075 Py_BEGIN_ALLOW_THREADS
3076 sync();
3077 Py_END_ALLOW_THREADS
3078 Py_RETURN_NONE;
3079}
Larry Hastings2f936352014-08-05 14:04:04 +10003080#endif /* HAVE_SYNC */
3081
Ross Lagerwall7807c352011-03-17 20:20:30 +02003082
Guido van Rossum21142a01999-01-08 21:05:37 +00003083#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003084#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003085extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3086#endif
3087
Larry Hastings2f936352014-08-05 14:04:04 +10003088/*[clinic input]
3089os.fdatasync
3090
3091 fd: fildes
3092
3093Force write of fd to disk without forcing update of metadata.
3094[clinic start generated code]*/
3095
Larry Hastings2f936352014-08-05 14:04:04 +10003096static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003097os_fdatasync_impl(PyObject *module, int fd)
3098/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003099{
3100 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003101}
3102#endif /* HAVE_FDATASYNC */
3103
3104
Fredrik Lundh10723342000-07-10 16:38:09 +00003105#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003106/*[clinic input]
3107os.chown
3108
3109 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3110 Path to be examined; can be string, bytes, or open-file-descriptor int.
3111
3112 uid: uid_t
3113
3114 gid: gid_t
3115
3116 *
3117
3118 dir_fd : dir_fd(requires='fchownat') = None
3119 If not None, it should be a file descriptor open to a directory,
3120 and path should be relative; path will then be relative to that
3121 directory.
3122
3123 follow_symlinks: bool = True
3124 If False, and the last element of the path is a symbolic link,
3125 stat will examine the symbolic link itself instead of the file
3126 the link points to.
3127
3128Change the owner and group id of path to the numeric uid and gid.\
3129
3130path may always be specified as a string.
3131On some platforms, path may also be specified as an open file descriptor.
3132 If this functionality is unavailable, using it raises an exception.
3133If dir_fd is not None, it should be a file descriptor open to a directory,
3134 and path should be relative; path will then be relative to that directory.
3135If follow_symlinks is False, and the last element of the path is a symbolic
3136 link, chown will modify the symbolic link itself instead of the file the
3137 link points to.
3138It is an error to use dir_fd or follow_symlinks when specifying path as
3139 an open file descriptor.
3140dir_fd and follow_symlinks may not be implemented on your platform.
3141 If they are unavailable, using them will raise a NotImplementedError.
3142
3143[clinic start generated code]*/
3144
Larry Hastings2f936352014-08-05 14:04:04 +10003145static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003146os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003147 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003148/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003149{
3150 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003151
3152#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3153 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003154 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003155#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003156 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3157 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3158 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159
3160#ifdef __APPLE__
3161 /*
3162 * This is for Mac OS X 10.3, which doesn't have lchown.
3163 * (But we still have an lchown symbol because of weak-linking.)
3164 * It doesn't have fchownat either. So there's no possibility
3165 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003166 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003167 if ((!follow_symlinks) && (lchown == NULL)) {
3168 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003169 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003170 }
3171#endif
3172
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003175 if (path->fd != -1)
3176 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177 else
3178#endif
3179#ifdef HAVE_LCHOWN
3180 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003181 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182 else
3183#endif
3184#ifdef HAVE_FCHOWNAT
3185 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003186 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3188 else
3189#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003190 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192
Larry Hastings2f936352014-08-05 14:04:04 +10003193 if (result)
3194 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003195
Larry Hastings2f936352014-08-05 14:04:04 +10003196 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003197}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003198#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003199
Larry Hastings2f936352014-08-05 14:04:04 +10003200
Christian Heimes4e30a842007-11-30 22:12:06 +00003201#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003202/*[clinic input]
3203os.fchown
3204
3205 fd: int
3206 uid: uid_t
3207 gid: gid_t
3208
3209Change the owner and group id of the file specified by file descriptor.
3210
3211Equivalent to os.chown(fd, uid, gid).
3212
3213[clinic start generated code]*/
3214
Larry Hastings2f936352014-08-05 14:04:04 +10003215static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003216os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3217/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003218{
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003220 int async_err = 0;
3221
3222 do {
3223 Py_BEGIN_ALLOW_THREADS
3224 res = fchown(fd, uid, gid);
3225 Py_END_ALLOW_THREADS
3226 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3227 if (res != 0)
3228 return (!async_err) ? posix_error() : NULL;
3229
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003231}
3232#endif /* HAVE_FCHOWN */
3233
Larry Hastings2f936352014-08-05 14:04:04 +10003234
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003235#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003236/*[clinic input]
3237os.lchown
3238
3239 path : path_t
3240 uid: uid_t
3241 gid: gid_t
3242
3243Change the owner and group id of path to the numeric uid and gid.
3244
3245This function will not follow symbolic links.
3246Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3247[clinic start generated code]*/
3248
Larry Hastings2f936352014-08-05 14:04:04 +10003249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003250os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3251/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003252{
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003255 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003257 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003258 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003259 }
Larry Hastings2f936352014-08-05 14:04:04 +10003260 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003261}
3262#endif /* HAVE_LCHOWN */
3263
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003264
Barry Warsaw53699e91996-12-10 23:23:01 +00003265static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003266posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003267{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003268 char *buf, *tmpbuf;
3269 char *cwd;
3270 const size_t chunk = 1024;
3271 size_t buflen = 0;
3272 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003273
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003274#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003276 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003277 wchar_t *wbuf2 = wbuf;
3278 PyObject *resobj;
3279 DWORD len;
3280 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003281 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 /* If the buffer is large enough, len does not include the
3283 terminating \0. If the buffer is too small, len includes
3284 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003285 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003286 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 if (wbuf2)
3288 len = GetCurrentDirectoryW(len, wbuf2);
3289 }
3290 Py_END_ALLOW_THREADS
3291 if (!wbuf2) {
3292 PyErr_NoMemory();
3293 return NULL;
3294 }
3295 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003296 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003297 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003298 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 }
3300 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003301 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003302 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003303 return resobj;
3304 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003305
3306 if (win32_warn_bytes_api())
3307 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003308#endif
3309
Victor Stinner4403d7d2015-04-25 00:16:10 +02003310 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003311 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003312 do {
3313 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003314#ifdef MS_WINDOWS
3315 if (buflen > INT_MAX) {
3316 PyErr_NoMemory();
3317 break;
3318 }
3319#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003320 tmpbuf = PyMem_RawRealloc(buf, buflen);
3321 if (tmpbuf == NULL)
3322 break;
3323
3324 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003325#ifdef MS_WINDOWS
3326 cwd = getcwd(buf, (int)buflen);
3327#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003328 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003329#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003330 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003331 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003332
3333 if (cwd == NULL) {
3334 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 }
3337
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003339 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3340 else
3341 obj = PyUnicode_DecodeFSDefault(buf);
3342 PyMem_RawFree(buf);
3343
3344 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003345}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003346
Larry Hastings2f936352014-08-05 14:04:04 +10003347
3348/*[clinic input]
3349os.getcwd
3350
3351Return a unicode string representing the current working directory.
3352[clinic start generated code]*/
3353
Larry Hastings2f936352014-08-05 14:04:04 +10003354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003355os_getcwd_impl(PyObject *module)
3356/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003357{
3358 return posix_getcwd(0);
3359}
3360
Larry Hastings2f936352014-08-05 14:04:04 +10003361
3362/*[clinic input]
3363os.getcwdb
3364
3365Return a bytes string representing the current working directory.
3366[clinic start generated code]*/
3367
Larry Hastings2f936352014-08-05 14:04:04 +10003368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003369os_getcwdb_impl(PyObject *module)
3370/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003371{
3372 return posix_getcwd(1);
3373}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003374
Larry Hastings2f936352014-08-05 14:04:04 +10003375
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3377#define HAVE_LINK 1
3378#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003379
Guido van Rossumb6775db1994-08-01 11:34:53 +00003380#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003381/*[clinic input]
3382
3383os.link
3384
3385 src : path_t
3386 dst : path_t
3387 *
3388 src_dir_fd : dir_fd = None
3389 dst_dir_fd : dir_fd = None
3390 follow_symlinks: bool = True
3391
3392Create a hard link to a file.
3393
3394If either src_dir_fd or dst_dir_fd is not None, it should be a file
3395 descriptor open to a directory, and the respective path string (src or dst)
3396 should be relative; the path will then be relative to that directory.
3397If follow_symlinks is False, and the last element of src is a symbolic
3398 link, link will create a link to the symbolic link itself instead of the
3399 file the link points to.
3400src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3401 platform. If they are unavailable, using them will raise a
3402 NotImplementedError.
3403[clinic start generated code]*/
3404
Larry Hastings2f936352014-08-05 14:04:04 +10003405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003406os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003407 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003408/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003409{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003411 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003412#else
3413 int result;
3414#endif
3415
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416#ifndef HAVE_LINKAT
3417 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3418 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003419 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420 }
3421#endif
3422
Steve Dowercc16be82016-09-08 10:35:16 -07003423#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003424 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 PyErr_SetString(PyExc_NotImplementedError,
3426 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003427 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 }
Steve Dowercc16be82016-09-08 10:35:16 -07003429#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003430
Brian Curtin1b9df392010-11-24 20:24:31 +00003431#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003433 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003435
Larry Hastings2f936352014-08-05 14:04:04 +10003436 if (!result)
3437 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438#else
3439 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003440#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3442 (dst_dir_fd != DEFAULT_DIR_FD) ||
3443 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003444 result = linkat(src_dir_fd, src->narrow,
3445 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3447 else
Steve Dowercc16be82016-09-08 10:35:16 -07003448#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003449 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003451
Larry Hastings2f936352014-08-05 14:04:04 +10003452 if (result)
3453 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003454#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455
Larry Hastings2f936352014-08-05 14:04:04 +10003456 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003457}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458#endif
3459
Brian Curtin1b9df392010-11-24 20:24:31 +00003460
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003461#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003462static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003463_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003464{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 PyObject *v;
3466 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3467 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003468 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003470 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472
Steve Dowercc16be82016-09-08 10:35:16 -07003473 WIN32_FIND_DATAW wFileData;
3474 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003475
Steve Dowercc16be82016-09-08 10:35:16 -07003476 if (!path->wide) { /* Default arg: "." */
3477 po_wchars = L".";
3478 len = 1;
3479 } else {
3480 po_wchars = path->wide;
3481 len = wcslen(path->wide);
3482 }
3483 /* The +5 is so we can append "\\*.*\0" */
3484 wnamebuf = PyMem_New(wchar_t, len + 5);
3485 if (!wnamebuf) {
3486 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 }
Steve Dowercc16be82016-09-08 10:35:16 -07003489 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003491 wchar_t wch = wnamebuf[len-1];
3492 if (wch != SEP && wch != ALTSEP && wch != L':')
3493 wnamebuf[len++] = SEP;
3494 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 }
Steve Dowercc16be82016-09-08 10:35:16 -07003496 if ((list = PyList_New(0)) == NULL) {
3497 goto exit;
3498 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003499 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003500 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003501 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 if (hFindFile == INVALID_HANDLE_VALUE) {
3503 int error = GetLastError();
3504 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 goto exit;
3506 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003507 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 }
3510 do {
3511 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003512 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3513 wcscmp(wFileData.cFileName, L"..") != 0) {
3514 v = PyUnicode_FromWideChar(wFileData.cFileName,
3515 wcslen(wFileData.cFileName));
3516 if (path->narrow && v) {
3517 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3518 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
3521 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 break;
3523 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_DECREF(list);
3527 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 break;
3529 }
3530 Py_DECREF(v);
3531 }
3532 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003533 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 Py_END_ALLOW_THREADS
3535 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3536 it got to the end of the directory. */
3537 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003539 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 }
3542 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003543
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544exit:
3545 if (hFindFile != INVALID_HANDLE_VALUE) {
3546 if (FindClose(hFindFile) == FALSE) {
3547 if (list != NULL) {
3548 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003549 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 }
3551 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003553 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003554
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003556} /* end of _listdir_windows_no_opendir */
3557
3558#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3559
3560static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003561_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003562{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003563 PyObject *v;
3564 DIR *dirp = NULL;
3565 struct dirent *ep;
3566 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003567#ifdef HAVE_FDOPENDIR
3568 int fd = -1;
3569#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003570
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003573 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003575 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003576 if (fd == -1)
3577 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578
Larry Hastingsfdaea062012-06-25 04:42:23 -07003579 return_str = 1;
3580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 Py_BEGIN_ALLOW_THREADS
3582 dirp = fdopendir(fd);
3583 Py_END_ALLOW_THREADS
3584 }
3585 else
3586#endif
3587 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003588 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003589 if (path->narrow) {
3590 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003591 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003592 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003593 }
3594 else {
3595 name = ".";
3596 return_str = 1;
3597 }
3598
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 Py_BEGIN_ALLOW_THREADS
3600 dirp = opendir(name);
3601 Py_END_ALLOW_THREADS
3602 }
3603
3604 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003605 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003606#ifdef HAVE_FDOPENDIR
3607 if (fd != -1) {
3608 Py_BEGIN_ALLOW_THREADS
3609 close(fd);
3610 Py_END_ALLOW_THREADS
3611 }
3612#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 goto exit;
3614 }
3615 if ((list = PyList_New(0)) == NULL) {
3616 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 }
3618 for (;;) {
3619 errno = 0;
3620 Py_BEGIN_ALLOW_THREADS
3621 ep = readdir(dirp);
3622 Py_END_ALLOW_THREADS
3623 if (ep == NULL) {
3624 if (errno == 0) {
3625 break;
3626 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003628 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 }
3631 }
3632 if (ep->d_name[0] == '.' &&
3633 (NAMLEN(ep) == 1 ||
3634 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3635 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003636 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003637 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3638 else
3639 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 break;
3643 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 break;
3648 }
3649 Py_DECREF(v);
3650 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003651
Larry Hastings9cf065c2012-06-22 16:30:09 -07003652exit:
3653 if (dirp != NULL) {
3654 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003655#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003656 if (fd > -1)
3657 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003658#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 closedir(dirp);
3660 Py_END_ALLOW_THREADS
3661 }
3662
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003664} /* end of _posix_listdir */
3665#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003666
Larry Hastings2f936352014-08-05 14:04:04 +10003667
3668/*[clinic input]
3669os.listdir
3670
3671 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3672
3673Return a list containing the names of the files in the directory.
3674
3675path can be specified as either str or bytes. If path is bytes,
3676 the filenames returned will also be bytes; in all other circumstances
3677 the filenames returned will be str.
3678If path is None, uses the path='.'.
3679On some platforms, path may also be specified as an open file descriptor;\
3680 the file descriptor must refer to a directory.
3681 If this functionality is unavailable, using it raises NotImplementedError.
3682
3683The list is in arbitrary order. It does not include the special
3684entries '.' and '..' even if they are present in the directory.
3685
3686
3687[clinic start generated code]*/
3688
Larry Hastings2f936352014-08-05 14:04:04 +10003689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003690os_listdir_impl(PyObject *module, path_t *path)
3691/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003692{
3693#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3694 return _listdir_windows_no_opendir(path, NULL);
3695#else
3696 return _posix_listdir(path, NULL);
3697#endif
3698}
3699
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003700#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003701/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003702/*[clinic input]
3703os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003704
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003705 path: path_t
3706 /
3707
3708[clinic start generated code]*/
3709
3710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003711os__getfullpathname_impl(PyObject *module, path_t *path)
3712/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003713{
Steve Dowercc16be82016-09-08 10:35:16 -07003714 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3715 wchar_t *wtemp;
3716 DWORD result;
3717 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003718
Steve Dowercc16be82016-09-08 10:35:16 -07003719 result = GetFullPathNameW(path->wide,
3720 Py_ARRAY_LENGTH(woutbuf),
3721 woutbuf, &wtemp);
3722 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3723 woutbufp = PyMem_New(wchar_t, result);
3724 if (!woutbufp)
3725 return PyErr_NoMemory();
3726 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 }
Steve Dowercc16be82016-09-08 10:35:16 -07003728 if (result) {
3729 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3730 if (path->narrow)
3731 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3732 } else
3733 v = win32_error_object("GetFullPathNameW", path->object);
3734 if (woutbufp != woutbuf)
3735 PyMem_Free(woutbufp);
3736 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003737}
Brian Curtind40e6f72010-07-08 21:39:08 +00003738
Brian Curtind25aef52011-06-13 15:16:04 -05003739
Larry Hastings2f936352014-08-05 14:04:04 +10003740/*[clinic input]
3741os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003742
Larry Hastings2f936352014-08-05 14:04:04 +10003743 path: unicode
3744 /
3745
3746A helper function for samepath on windows.
3747[clinic start generated code]*/
3748
Larry Hastings2f936352014-08-05 14:04:04 +10003749static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003750os__getfinalpathname_impl(PyObject *module, PyObject *path)
3751/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003752{
3753 HANDLE hFile;
3754 int buf_size;
3755 wchar_t *target_path;
3756 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003757 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003758 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003759
Larry Hastings2f936352014-08-05 14:04:04 +10003760 path_wchar = PyUnicode_AsUnicode(path);
3761 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003762 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003763
Brian Curtind40e6f72010-07-08 21:39:08 +00003764 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003765 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003766 0, /* desired access */
3767 0, /* share mode */
3768 NULL, /* security attributes */
3769 OPEN_EXISTING,
3770 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3771 FILE_FLAG_BACKUP_SEMANTICS,
3772 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003773
Victor Stinnereb5657a2011-09-30 01:44:27 +02003774 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003775 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003776
3777 /* We have a good handle to the target, use it to determine the
3778 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003779 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003780
3781 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003782 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003783
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003784 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003785 if(!target_path)
3786 return PyErr_NoMemory();
3787
Steve Dower2ea51c92015-03-20 21:49:12 -07003788 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3789 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003790 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003791 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003792
3793 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003794 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003795
3796 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003797 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003798 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003799 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003800}
Brian Curtin62857742010-09-06 17:07:27 +00003801
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003802/*[clinic input]
3803os._isdir
3804
3805 path: path_t
3806 /
3807
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003808Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003809[clinic start generated code]*/
3810
Brian Curtin9c669cc2011-06-08 18:17:18 -05003811static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003812os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003813/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003814{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003815 DWORD attributes;
3816
Steve Dowerb22a6772016-07-17 20:49:38 -07003817 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003818 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003819 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003820
Brian Curtin9c669cc2011-06-08 18:17:18 -05003821 if (attributes == INVALID_FILE_ATTRIBUTES)
3822 Py_RETURN_FALSE;
3823
Brian Curtin9c669cc2011-06-08 18:17:18 -05003824 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3825 Py_RETURN_TRUE;
3826 else
3827 Py_RETURN_FALSE;
3828}
Tim Golden6b528062013-08-01 12:44:00 +01003829
Tim Golden6b528062013-08-01 12:44:00 +01003830
Larry Hastings2f936352014-08-05 14:04:04 +10003831/*[clinic input]
3832os._getvolumepathname
3833
3834 path: unicode
3835
3836A helper function for ismount on Win32.
3837[clinic start generated code]*/
3838
Larry Hastings2f936352014-08-05 14:04:04 +10003839static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003840os__getvolumepathname_impl(PyObject *module, PyObject *path)
3841/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003842{
3843 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003844 const wchar_t *path_wchar;
3845 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003846 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003847 BOOL ret;
3848
Larry Hastings2f936352014-08-05 14:04:04 +10003849 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3850 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003851 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003852 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003853
3854 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003855 buflen = Py_MAX(buflen, MAX_PATH);
3856
3857 if (buflen > DWORD_MAX) {
3858 PyErr_SetString(PyExc_OverflowError, "path too long");
3859 return NULL;
3860 }
3861
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003862 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003863 if (mountpath == NULL)
3864 return PyErr_NoMemory();
3865
3866 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003867 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003868 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003869 Py_END_ALLOW_THREADS
3870
3871 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003872 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003873 goto exit;
3874 }
3875 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3876
3877exit:
3878 PyMem_Free(mountpath);
3879 return result;
3880}
Tim Golden6b528062013-08-01 12:44:00 +01003881
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003882#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003883
Larry Hastings2f936352014-08-05 14:04:04 +10003884
3885/*[clinic input]
3886os.mkdir
3887
3888 path : path_t
3889
3890 mode: int = 0o777
3891
3892 *
3893
3894 dir_fd : dir_fd(requires='mkdirat') = None
3895
3896# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3897
3898Create a directory.
3899
3900If dir_fd is not None, it should be a file descriptor open to a directory,
3901 and path should be relative; path will then be relative to that directory.
3902dir_fd may not be implemented on your platform.
3903 If it is unavailable, using it will raise a NotImplementedError.
3904
3905The mode argument is ignored on Windows.
3906[clinic start generated code]*/
3907
Larry Hastings2f936352014-08-05 14:04:04 +10003908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003909os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3910/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003911{
3912 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003913
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003914#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003916 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003918
Larry Hastings2f936352014-08-05 14:04:04 +10003919 if (!result)
3920 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003921#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003923#if HAVE_MKDIRAT
3924 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003925 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003926 else
3927#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003928#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003929 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003930#else
Larry Hastings2f936352014-08-05 14:04:04 +10003931 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003932#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003933 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003934 if (result < 0)
3935 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003936#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003937 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003938}
3939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003940
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003941/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3942#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003943#include <sys/resource.h>
3944#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003945
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003946
3947#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003948/*[clinic input]
3949os.nice
3950
3951 increment: int
3952 /
3953
3954Add increment to the priority of process and return the new priority.
3955[clinic start generated code]*/
3956
Larry Hastings2f936352014-08-05 14:04:04 +10003957static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003958os_nice_impl(PyObject *module, int increment)
3959/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003960{
3961 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003962
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 /* There are two flavours of 'nice': one that returns the new
3964 priority (as required by almost all standards out there) and the
3965 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3966 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003967
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 If we are of the nice family that returns the new priority, we
3969 need to clear errno before the call, and check if errno is filled
3970 before calling posix_error() on a returnvalue of -1, because the
3971 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003972
Victor Stinner8c62be82010-05-06 00:08:46 +00003973 errno = 0;
3974 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003975#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003976 if (value == 0)
3977 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003978#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003979 if (value == -1 && errno != 0)
3980 /* either nice() or getpriority() returned an error */
3981 return posix_error();
3982 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003983}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003984#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003985
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003986
3987#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003988/*[clinic input]
3989os.getpriority
3990
3991 which: int
3992 who: int
3993
3994Return program scheduling priority.
3995[clinic start generated code]*/
3996
Larry Hastings2f936352014-08-05 14:04:04 +10003997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003998os_getpriority_impl(PyObject *module, int which, int who)
3999/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004000{
4001 int retval;
4002
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004003 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004004 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004005 if (errno != 0)
4006 return posix_error();
4007 return PyLong_FromLong((long)retval);
4008}
4009#endif /* HAVE_GETPRIORITY */
4010
4011
4012#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004013/*[clinic input]
4014os.setpriority
4015
4016 which: int
4017 who: int
4018 priority: int
4019
4020Set program scheduling priority.
4021[clinic start generated code]*/
4022
Larry Hastings2f936352014-08-05 14:04:04 +10004023static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004024os_setpriority_impl(PyObject *module, int which, int who, int priority)
4025/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004026{
4027 int retval;
4028
4029 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004030 if (retval == -1)
4031 return posix_error();
4032 Py_RETURN_NONE;
4033}
4034#endif /* HAVE_SETPRIORITY */
4035
4036
Barry Warsaw53699e91996-12-10 23:23:01 +00004037static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004038internal_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 +00004039{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004040 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004041 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004043#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004045 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004046#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004048#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049
Larry Hastings9cf065c2012-06-22 16:30:09 -07004050 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4051 (dst_dir_fd != DEFAULT_DIR_FD);
4052#ifndef HAVE_RENAMEAT
4053 if (dir_fd_specified) {
4054 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004055 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004056 }
4057#endif
4058
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059#ifdef MS_WINDOWS
4060 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004061 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004062 Py_END_ALLOW_THREADS
4063
Larry Hastings2f936352014-08-05 14:04:04 +10004064 if (!result)
4065 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004066
4067#else
Steve Dowercc16be82016-09-08 10:35:16 -07004068 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4069 PyErr_Format(PyExc_ValueError,
4070 "%s: src and dst must be the same type", function_name);
4071 return NULL;
4072 }
4073
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074 Py_BEGIN_ALLOW_THREADS
4075#ifdef HAVE_RENAMEAT
4076 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004077 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078 else
4079#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004080 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081 Py_END_ALLOW_THREADS
4082
Larry Hastings2f936352014-08-05 14:04:04 +10004083 if (result)
4084 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004085#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004086 Py_RETURN_NONE;
4087}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088
Larry Hastings2f936352014-08-05 14:04:04 +10004089
4090/*[clinic input]
4091os.rename
4092
4093 src : path_t
4094 dst : path_t
4095 *
4096 src_dir_fd : dir_fd = None
4097 dst_dir_fd : dir_fd = None
4098
4099Rename a file or directory.
4100
4101If either src_dir_fd or dst_dir_fd is not None, it should be a file
4102 descriptor open to a directory, and the respective path string (src or dst)
4103 should be relative; the path will then be relative to that directory.
4104src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4105 If they are unavailable, using them will raise a NotImplementedError.
4106[clinic start generated code]*/
4107
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004109os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004110 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004111/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004112{
Larry Hastings2f936352014-08-05 14:04:04 +10004113 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004114}
4115
Larry Hastings2f936352014-08-05 14:04:04 +10004116
4117/*[clinic input]
4118os.replace = os.rename
4119
4120Rename a file or directory, overwriting the destination.
4121
4122If either src_dir_fd or dst_dir_fd is not None, it should be a file
4123 descriptor open to a directory, and the respective path string (src or dst)
4124 should be relative; the path will then be relative to that directory.
4125src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4126 If they are unavailable, using them will raise a NotImplementedError."
4127[clinic start generated code]*/
4128
Larry Hastings2f936352014-08-05 14:04:04 +10004129static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004130os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4131 int dst_dir_fd)
4132/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004133{
4134 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4135}
4136
4137
4138/*[clinic input]
4139os.rmdir
4140
4141 path: path_t
4142 *
4143 dir_fd: dir_fd(requires='unlinkat') = None
4144
4145Remove a directory.
4146
4147If dir_fd is not None, it should be a file descriptor open to a directory,
4148 and path should be relative; path will then be relative to that directory.
4149dir_fd may not be implemented on your platform.
4150 If it is unavailable, using it will raise a NotImplementedError.
4151[clinic start generated code]*/
4152
Larry Hastings2f936352014-08-05 14:04:04 +10004153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004154os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4155/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004156{
4157 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004158
4159 Py_BEGIN_ALLOW_THREADS
4160#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004161 /* Windows, success=1, UNIX, success=0 */
4162 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004163#else
4164#ifdef HAVE_UNLINKAT
4165 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004166 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004167 else
4168#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004169 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004170#endif
4171 Py_END_ALLOW_THREADS
4172
Larry Hastings2f936352014-08-05 14:04:04 +10004173 if (result)
4174 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004175
Larry Hastings2f936352014-08-05 14:04:04 +10004176 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004177}
4178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004179
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004180#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004181#ifdef MS_WINDOWS
4182/*[clinic input]
4183os.system -> long
4184
4185 command: Py_UNICODE
4186
4187Execute the command in a subshell.
4188[clinic start generated code]*/
4189
Larry Hastings2f936352014-08-05 14:04:04 +10004190static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004191os_system_impl(PyObject *module, Py_UNICODE *command)
4192/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004193{
4194 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004196 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004197 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004198 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004200 return result;
4201}
4202#else /* MS_WINDOWS */
4203/*[clinic input]
4204os.system -> long
4205
4206 command: FSConverter
4207
4208Execute the command in a subshell.
4209[clinic start generated code]*/
4210
Larry Hastings2f936352014-08-05 14:04:04 +10004211static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004212os_system_impl(PyObject *module, PyObject *command)
4213/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004214{
4215 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004216 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004217 Py_BEGIN_ALLOW_THREADS
4218 result = system(bytes);
4219 Py_END_ALLOW_THREADS
4220 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004221}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004222#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004223#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004225
Larry Hastings2f936352014-08-05 14:04:04 +10004226/*[clinic input]
4227os.umask
4228
4229 mask: int
4230 /
4231
4232Set the current numeric umask and return the previous umask.
4233[clinic start generated code]*/
4234
Larry Hastings2f936352014-08-05 14:04:04 +10004235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004236os_umask_impl(PyObject *module, int mask)
4237/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004238{
4239 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004240 if (i < 0)
4241 return posix_error();
4242 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004243}
4244
Brian Curtind40e6f72010-07-08 21:39:08 +00004245#ifdef MS_WINDOWS
4246
4247/* override the default DeleteFileW behavior so that directory
4248symlinks can be removed with this function, the same as with
4249Unix symlinks */
4250BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4251{
4252 WIN32_FILE_ATTRIBUTE_DATA info;
4253 WIN32_FIND_DATAW find_data;
4254 HANDLE find_data_handle;
4255 int is_directory = 0;
4256 int is_link = 0;
4257
4258 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4259 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004260
Brian Curtind40e6f72010-07-08 21:39:08 +00004261 /* Get WIN32_FIND_DATA structure for the path to determine if
4262 it is a symlink */
4263 if(is_directory &&
4264 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4265 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4266
4267 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004268 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4269 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4270 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4271 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004272 FindClose(find_data_handle);
4273 }
4274 }
4275 }
4276
4277 if (is_directory && is_link)
4278 return RemoveDirectoryW(lpFileName);
4279
4280 return DeleteFileW(lpFileName);
4281}
4282#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004284
Larry Hastings2f936352014-08-05 14:04:04 +10004285/*[clinic input]
4286os.unlink
4287
4288 path: path_t
4289 *
4290 dir_fd: dir_fd(requires='unlinkat')=None
4291
4292Remove a file (same as remove()).
4293
4294If dir_fd is not None, it should be a file descriptor open to a directory,
4295 and path should be relative; path will then be relative to that directory.
4296dir_fd may not be implemented on your platform.
4297 If it is unavailable, using it will raise a NotImplementedError.
4298
4299[clinic start generated code]*/
4300
Larry Hastings2f936352014-08-05 14:04:04 +10004301static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004302os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4303/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004304{
4305 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306
4307 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004308 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004309#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004310 /* Windows, success=1, UNIX, success=0 */
4311 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004313#ifdef HAVE_UNLINKAT
4314 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004315 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004316 else
4317#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004318 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004319#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004320 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004321 Py_END_ALLOW_THREADS
4322
Larry Hastings2f936352014-08-05 14:04:04 +10004323 if (result)
4324 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004325
Larry Hastings2f936352014-08-05 14:04:04 +10004326 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004327}
4328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Larry Hastings2f936352014-08-05 14:04:04 +10004330/*[clinic input]
4331os.remove = os.unlink
4332
4333Remove a file (same as unlink()).
4334
4335If dir_fd is not None, it should be a file descriptor open to a directory,
4336 and path should be relative; path will then be relative to that directory.
4337dir_fd may not be implemented on your platform.
4338 If it is unavailable, using it will raise a NotImplementedError.
4339[clinic start generated code]*/
4340
Larry Hastings2f936352014-08-05 14:04:04 +10004341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004342os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4343/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004344{
4345 return os_unlink_impl(module, path, dir_fd);
4346}
4347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004348
Larry Hastings605a62d2012-06-24 04:33:36 -07004349static PyStructSequence_Field uname_result_fields[] = {
4350 {"sysname", "operating system name"},
4351 {"nodename", "name of machine on network (implementation-defined)"},
4352 {"release", "operating system release"},
4353 {"version", "operating system version"},
4354 {"machine", "hardware identifier"},
4355 {NULL}
4356};
4357
4358PyDoc_STRVAR(uname_result__doc__,
4359"uname_result: Result from os.uname().\n\n\
4360This object may be accessed either as a tuple of\n\
4361 (sysname, nodename, release, version, machine),\n\
4362or via the attributes sysname, nodename, release, version, and machine.\n\
4363\n\
4364See os.uname for more information.");
4365
4366static PyStructSequence_Desc uname_result_desc = {
4367 "uname_result", /* name */
4368 uname_result__doc__, /* doc */
4369 uname_result_fields,
4370 5
4371};
4372
4373static PyTypeObject UnameResultType;
4374
4375
4376#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004377/*[clinic input]
4378os.uname
4379
4380Return an object identifying the current operating system.
4381
4382The object behaves like a named tuple with the following fields:
4383 (sysname, nodename, release, version, machine)
4384
4385[clinic start generated code]*/
4386
Larry Hastings2f936352014-08-05 14:04:04 +10004387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004388os_uname_impl(PyObject *module)
4389/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004390{
Victor Stinner8c62be82010-05-06 00:08:46 +00004391 struct utsname u;
4392 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004393 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004394
Victor Stinner8c62be82010-05-06 00:08:46 +00004395 Py_BEGIN_ALLOW_THREADS
4396 res = uname(&u);
4397 Py_END_ALLOW_THREADS
4398 if (res < 0)
4399 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004400
4401 value = PyStructSequence_New(&UnameResultType);
4402 if (value == NULL)
4403 return NULL;
4404
4405#define SET(i, field) \
4406 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004407 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004408 if (!o) { \
4409 Py_DECREF(value); \
4410 return NULL; \
4411 } \
4412 PyStructSequence_SET_ITEM(value, i, o); \
4413 } \
4414
4415 SET(0, u.sysname);
4416 SET(1, u.nodename);
4417 SET(2, u.release);
4418 SET(3, u.version);
4419 SET(4, u.machine);
4420
4421#undef SET
4422
4423 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004424}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004425#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004426
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004427
Larry Hastings9cf065c2012-06-22 16:30:09 -07004428
4429typedef struct {
4430 int now;
4431 time_t atime_s;
4432 long atime_ns;
4433 time_t mtime_s;
4434 long mtime_ns;
4435} utime_t;
4436
4437/*
Victor Stinner484df002014-10-09 13:52:31 +02004438 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 * they also intentionally leak the declaration of a pointer named "time"
4440 */
4441#define UTIME_TO_TIMESPEC \
4442 struct timespec ts[2]; \
4443 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004444 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004445 time = NULL; \
4446 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004447 ts[0].tv_sec = ut->atime_s; \
4448 ts[0].tv_nsec = ut->atime_ns; \
4449 ts[1].tv_sec = ut->mtime_s; \
4450 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451 time = ts; \
4452 } \
4453
4454#define UTIME_TO_TIMEVAL \
4455 struct timeval tv[2]; \
4456 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004457 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004458 time = NULL; \
4459 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004460 tv[0].tv_sec = ut->atime_s; \
4461 tv[0].tv_usec = ut->atime_ns / 1000; \
4462 tv[1].tv_sec = ut->mtime_s; \
4463 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004464 time = tv; \
4465 } \
4466
4467#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004468 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004470 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004471 time = NULL; \
4472 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004473 u.actime = ut->atime_s; \
4474 u.modtime = ut->mtime_s; \
4475 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476 }
4477
4478#define UTIME_TO_TIME_T \
4479 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004480 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004481 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004482 time = NULL; \
4483 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004484 timet[0] = ut->atime_s; \
4485 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004486 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487 } \
4488
4489
Victor Stinner528a9ab2015-09-03 21:30:26 +02004490#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004491
4492static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004493utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004494{
4495#ifdef HAVE_UTIMENSAT
4496 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4497 UTIME_TO_TIMESPEC;
4498 return utimensat(dir_fd, path, time, flags);
4499#elif defined(HAVE_FUTIMESAT)
4500 UTIME_TO_TIMEVAL;
4501 /*
4502 * follow_symlinks will never be false here;
4503 * we only allow !follow_symlinks and dir_fd together
4504 * if we have utimensat()
4505 */
4506 assert(follow_symlinks);
4507 return futimesat(dir_fd, path, time);
4508#endif
4509}
4510
Larry Hastings2f936352014-08-05 14:04:04 +10004511 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4512#else
4513 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514#endif
4515
Victor Stinner528a9ab2015-09-03 21:30:26 +02004516#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517
4518static int
Victor Stinner484df002014-10-09 13:52:31 +02004519utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520{
4521#ifdef HAVE_FUTIMENS
4522 UTIME_TO_TIMESPEC;
4523 return futimens(fd, time);
4524#else
4525 UTIME_TO_TIMEVAL;
4526 return futimes(fd, time);
4527#endif
4528}
4529
Larry Hastings2f936352014-08-05 14:04:04 +10004530 #define PATH_UTIME_HAVE_FD 1
4531#else
4532 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533#endif
4534
Victor Stinner5ebae872015-09-22 01:29:33 +02004535#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4536# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4537#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538
Victor Stinner4552ced2015-09-21 22:37:15 +02004539#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540
4541static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004542utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543{
4544#ifdef HAVE_UTIMENSAT
4545 UTIME_TO_TIMESPEC;
4546 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4547#else
4548 UTIME_TO_TIMEVAL;
4549 return lutimes(path, time);
4550#endif
4551}
4552
4553#endif
4554
4555#ifndef MS_WINDOWS
4556
4557static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004558utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559{
4560#ifdef HAVE_UTIMENSAT
4561 UTIME_TO_TIMESPEC;
4562 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4563#elif defined(HAVE_UTIMES)
4564 UTIME_TO_TIMEVAL;
4565 return utimes(path, time);
4566#elif defined(HAVE_UTIME_H)
4567 UTIME_TO_UTIMBUF;
4568 return utime(path, time);
4569#else
4570 UTIME_TO_TIME_T;
4571 return utime(path, time);
4572#endif
4573}
4574
4575#endif
4576
Larry Hastings76ad59b2012-05-03 00:30:07 -07004577static int
4578split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4579{
4580 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004581 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004582 divmod = PyNumber_Divmod(py_long, billion);
4583 if (!divmod)
4584 goto exit;
4585 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4586 if ((*s == -1) && PyErr_Occurred())
4587 goto exit;
4588 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004589 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590 goto exit;
4591
4592 result = 1;
4593exit:
4594 Py_XDECREF(divmod);
4595 return result;
4596}
4597
Larry Hastings2f936352014-08-05 14:04:04 +10004598
4599/*[clinic input]
4600os.utime
4601
4602 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4603 times: object = NULL
4604 *
4605 ns: object = NULL
4606 dir_fd: dir_fd(requires='futimensat') = None
4607 follow_symlinks: bool=True
4608
Martin Panter0ff89092015-09-09 01:56:53 +00004609# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004610
4611Set the access and modified time of path.
4612
4613path may always be specified as a string.
4614On some platforms, path may also be specified as an open file descriptor.
4615 If this functionality is unavailable, using it raises an exception.
4616
4617If times is not None, it must be a tuple (atime, mtime);
4618 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004619If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004620 atime_ns and mtime_ns should be expressed as integer nanoseconds
4621 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004622If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004623Specifying tuples for both times and ns is an error.
4624
4625If dir_fd is not None, it should be a file descriptor open to a directory,
4626 and path should be relative; path will then be relative to that directory.
4627If follow_symlinks is False, and the last element of the path is a symbolic
4628 link, utime will modify the symbolic link itself instead of the file the
4629 link points to.
4630It is an error to use dir_fd or follow_symlinks when specifying path
4631 as an open file descriptor.
4632dir_fd and follow_symlinks may not be available on your platform.
4633 If they are unavailable, using them will raise a NotImplementedError.
4634
4635[clinic start generated code]*/
4636
Larry Hastings2f936352014-08-05 14:04:04 +10004637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004638os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4639 int dir_fd, int follow_symlinks)
4640/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004641{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642#ifdef MS_WINDOWS
4643 HANDLE hFile;
4644 FILETIME atime, mtime;
4645#else
4646 int result;
4647#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004648
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004650 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004651
Christian Heimesb3c87242013-08-01 00:08:16 +02004652 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 if (times && (times != Py_None) && ns) {
4655 PyErr_SetString(PyExc_ValueError,
4656 "utime: you may specify either 'times'"
4657 " or 'ns' but not both");
4658 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004659 }
4660
4661 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004662 time_t a_sec, m_sec;
4663 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004664 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 PyErr_SetString(PyExc_TypeError,
4666 "utime: 'times' must be either"
4667 " a tuple of two ints or None");
4668 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004669 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004670 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004671 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004672 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004673 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004674 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004676 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004677 utime.atime_s = a_sec;
4678 utime.atime_ns = a_nsec;
4679 utime.mtime_s = m_sec;
4680 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004683 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004684 PyErr_SetString(PyExc_TypeError,
4685 "utime: 'ns' must be a tuple of two ints");
4686 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004687 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004689 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004691 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692 &utime.mtime_s, &utime.mtime_ns)) {
4693 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004694 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695 }
4696 else {
4697 /* times and ns are both None/unspecified. use "now". */
4698 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004699 }
4700
Victor Stinner4552ced2015-09-21 22:37:15 +02004701#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 if (follow_symlinks_specified("utime", follow_symlinks))
4703 goto exit;
4704#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004705
Larry Hastings2f936352014-08-05 14:04:04 +10004706 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4707 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4708 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004710
Larry Hastings9cf065c2012-06-22 16:30:09 -07004711#if !defined(HAVE_UTIMENSAT)
4712 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004713 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 "utime: cannot use dir_fd and follow_symlinks "
4715 "together on this platform");
4716 goto exit;
4717 }
4718#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004719
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004720#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004722 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4723 NULL, OPEN_EXISTING,
4724 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 Py_END_ALLOW_THREADS
4726 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004727 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004728 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004729 }
4730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004732 GetSystemTimeAsFileTime(&mtime);
4733 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004736 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4737 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 }
4739 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4740 /* Avoid putting the file name into the error here,
4741 as that may confuse the user into believing that
4742 something is wrong with the file, when it also
4743 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004744 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004746 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004747#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004749
Victor Stinner4552ced2015-09-21 22:37:15 +02004750#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004752 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004754#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755
Victor Stinner528a9ab2015-09-03 21:30:26 +02004756#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004758 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 else
4760#endif
4761
Victor Stinner528a9ab2015-09-03 21:30:26 +02004762#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004763 if (path->fd != -1)
4764 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 else
4766#endif
4767
Larry Hastings2f936352014-08-05 14:04:04 +10004768 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769
4770 Py_END_ALLOW_THREADS
4771
4772 if (result < 0) {
4773 /* see previous comment about not putting filename in error here */
4774 return_value = posix_error();
4775 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004778#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779
4780 Py_INCREF(Py_None);
4781 return_value = Py_None;
4782
4783exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784#ifdef MS_WINDOWS
4785 if (hFile != INVALID_HANDLE_VALUE)
4786 CloseHandle(hFile);
4787#endif
4788 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004789}
4790
Guido van Rossum3b066191991-06-04 19:40:25 +00004791/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004792
Larry Hastings2f936352014-08-05 14:04:04 +10004793
4794/*[clinic input]
4795os._exit
4796
4797 status: int
4798
4799Exit to the system with specified status, without normal exit processing.
4800[clinic start generated code]*/
4801
Larry Hastings2f936352014-08-05 14:04:04 +10004802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004803os__exit_impl(PyObject *module, int status)
4804/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004805{
4806 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004807 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004808}
4809
Steve Dowercc16be82016-09-08 10:35:16 -07004810#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4811#define EXECV_CHAR wchar_t
4812#else
4813#define EXECV_CHAR char
4814#endif
4815
Martin v. Löwis114619e2002-10-07 06:44:21 +00004816#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4817static void
Steve Dowercc16be82016-09-08 10:35:16 -07004818free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004819{
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 Py_ssize_t i;
4821 for (i = 0; i < count; i++)
4822 PyMem_Free(array[i]);
4823 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004824}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004825
Berker Peksag81816462016-09-15 20:19:47 +03004826static int
4827fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004828{
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004830 PyObject *ub;
4831 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004832#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004833 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004834 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004835 *out = PyUnicode_AsWideCharString(ub, &size);
4836 if (*out)
4837 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004838#else
Berker Peksag81816462016-09-15 20:19:47 +03004839 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004840 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004841 size = PyBytes_GET_SIZE(ub);
4842 *out = PyMem_Malloc(size + 1);
4843 if (*out) {
4844 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4845 result = 1;
4846 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004847 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004848#endif
Berker Peksag81816462016-09-15 20:19:47 +03004849 Py_DECREF(ub);
4850 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004851}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004852#endif
4853
Ross Lagerwall7807c352011-03-17 20:20:30 +02004854#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004855static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004856parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4857{
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 Py_ssize_t i, pos, envc;
4859 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004860 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004861 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004862
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 i = PyMapping_Size(env);
4864 if (i < 0)
4865 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004866 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 if (envlist == NULL) {
4868 PyErr_NoMemory();
4869 return NULL;
4870 }
4871 envc = 0;
4872 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004873 if (!keys)
4874 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004876 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004877 goto error;
4878 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4879 PyErr_Format(PyExc_TypeError,
4880 "env.keys() or env.values() is not a list");
4881 goto error;
4882 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004883
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 for (pos = 0; pos < i; pos++) {
4885 key = PyList_GetItem(keys, pos);
4886 val = PyList_GetItem(vals, pos);
4887 if (!key || !val)
4888 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004889
Berker Peksag81816462016-09-15 20:19:47 +03004890#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4891 if (!PyUnicode_FSDecoder(key, &key2))
4892 goto error;
4893 if (!PyUnicode_FSDecoder(val, &val2)) {
4894 Py_DECREF(key2);
4895 goto error;
4896 }
4897 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4898#else
4899 if (!PyUnicode_FSConverter(key, &key2))
4900 goto error;
4901 if (!PyUnicode_FSConverter(val, &val2)) {
4902 Py_DECREF(key2);
4903 goto error;
4904 }
4905 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4906 PyBytes_AS_STRING(val2));
4907#endif
4908 Py_DECREF(key2);
4909 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004910 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004912
4913 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4914 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 goto error;
4916 }
Berker Peksag81816462016-09-15 20:19:47 +03004917
Steve Dowercc16be82016-09-08 10:35:16 -07004918 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 }
4920 Py_DECREF(vals);
4921 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004922
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 envlist[envc] = 0;
4924 *envc_ptr = envc;
4925 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004926
4927error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 Py_XDECREF(keys);
4929 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004930 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004931 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004932}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004933
Steve Dowercc16be82016-09-08 10:35:16 -07004934static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004935parse_arglist(PyObject* argv, Py_ssize_t *argc)
4936{
4937 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004938 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004939 if (argvlist == NULL) {
4940 PyErr_NoMemory();
4941 return NULL;
4942 }
4943 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004944 PyObject* item = PySequence_ITEM(argv, i);
4945 if (item == NULL)
4946 goto fail;
4947 if (!fsconvert_strdup(item, &argvlist[i])) {
4948 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949 goto fail;
4950 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004951 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004952 }
4953 argvlist[*argc] = NULL;
4954 return argvlist;
4955fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004956 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004957 free_string_array(argvlist, *argc);
4958 return NULL;
4959}
Steve Dowercc16be82016-09-08 10:35:16 -07004960
Ross Lagerwall7807c352011-03-17 20:20:30 +02004961#endif
4962
Larry Hastings2f936352014-08-05 14:04:04 +10004963
Ross Lagerwall7807c352011-03-17 20:20:30 +02004964#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004965/*[clinic input]
4966os.execv
4967
Steve Dowercc16be82016-09-08 10:35:16 -07004968 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004969 Path of executable file.
4970 argv: object
4971 Tuple or list of strings.
4972 /
4973
4974Execute an executable path with arguments, replacing current process.
4975[clinic start generated code]*/
4976
Larry Hastings2f936352014-08-05 14:04:04 +10004977static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004978os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4979/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004980{
Steve Dowercc16be82016-09-08 10:35:16 -07004981 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004982 Py_ssize_t argc;
4983
4984 /* execv has two arguments: (path, argv), where
4985 argv is a list or tuple of strings. */
4986
Ross Lagerwall7807c352011-03-17 20:20:30 +02004987 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4988 PyErr_SetString(PyExc_TypeError,
4989 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004990 return NULL;
4991 }
4992 argc = PySequence_Size(argv);
4993 if (argc < 1) {
4994 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004995 return NULL;
4996 }
4997
4998 argvlist = parse_arglist(argv, &argc);
4999 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005000 return NULL;
5001 }
Steve Dowerbce26262016-11-19 19:17:26 -08005002 if (!argvlist[0][0]) {
5003 PyErr_SetString(PyExc_ValueError,
5004 "execv() arg 2 first element cannot be empty");
5005 free_string_array(argvlist, argc);
5006 return NULL;
5007 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005008
Steve Dowerbce26262016-11-19 19:17:26 -08005009 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005010#ifdef HAVE_WEXECV
5011 _wexecv(path->wide, argvlist);
5012#else
5013 execv(path->narrow, argvlist);
5014#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005015 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016
5017 /* If we get here it's definitely an error */
5018
5019 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005020 return posix_error();
5021}
5022
Larry Hastings2f936352014-08-05 14:04:04 +10005023
5024/*[clinic input]
5025os.execve
5026
5027 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5028 Path of executable file.
5029 argv: object
5030 Tuple or list of strings.
5031 env: object
5032 Dictionary of strings mapping to strings.
5033
5034Execute an executable path with arguments, replacing current process.
5035[clinic start generated code]*/
5036
Larry Hastings2f936352014-08-05 14:04:04 +10005037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005038os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5039/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005040{
Steve Dowercc16be82016-09-08 10:35:16 -07005041 EXECV_CHAR **argvlist = NULL;
5042 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005044
Victor Stinner8c62be82010-05-06 00:08:46 +00005045 /* execve has three arguments: (path, argv, env), where
5046 argv is a list or tuple of strings and env is a dictionary
5047 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005048
Ross Lagerwall7807c352011-03-17 20:20:30 +02005049 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005051 "execve: argv must be a tuple or list");
5052 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005054 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005055 if (argc < 1) {
5056 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5057 return NULL;
5058 }
5059
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 if (!PyMapping_Check(env)) {
5061 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005062 "execve: environment must be a mapping object");
5063 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005065
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005068 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 }
Steve Dowerbce26262016-11-19 19:17:26 -08005070 if (!argvlist[0][0]) {
5071 PyErr_SetString(PyExc_ValueError,
5072 "execve: argv first element cannot be empty");
5073 goto fail;
5074 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005075
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 envlist = parse_envlist(env, &envc);
5077 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005078 goto fail;
5079
Steve Dowerbce26262016-11-19 19:17:26 -08005080 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005081#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005082 if (path->fd > -1)
5083 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005084 else
5085#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005086#ifdef HAVE_WEXECV
5087 _wexecve(path->wide, argvlist, envlist);
5088#else
Larry Hastings2f936352014-08-05 14:04:04 +10005089 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005090#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005091 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005092
5093 /* If we get here it's definitely an error */
5094
Larry Hastings2f936352014-08-05 14:04:04 +10005095 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005096
Steve Dowercc16be82016-09-08 10:35:16 -07005097 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005098 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005099 if (argvlist)
5100 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005101 return NULL;
5102}
Steve Dowercc16be82016-09-08 10:35:16 -07005103
Larry Hastings9cf065c2012-06-22 16:30:09 -07005104#endif /* HAVE_EXECV */
5105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005106
Steve Dowercc16be82016-09-08 10:35:16 -07005107#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005108/*[clinic input]
5109os.spawnv
5110
5111 mode: int
5112 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005113 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005114 Path of executable file.
5115 argv: object
5116 Tuple or list of strings.
5117 /
5118
5119Execute the program specified by path in a new process.
5120[clinic start generated code]*/
5121
Larry Hastings2f936352014-08-05 14:04:04 +10005122static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005123os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5124/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005125{
Steve Dowercc16be82016-09-08 10:35:16 -07005126 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005127 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005129 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005131
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 /* spawnv has three arguments: (mode, path, argv), where
5133 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005134
Victor Stinner8c62be82010-05-06 00:08:46 +00005135 if (PyList_Check(argv)) {
5136 argc = PyList_Size(argv);
5137 getitem = PyList_GetItem;
5138 }
5139 else if (PyTuple_Check(argv)) {
5140 argc = PyTuple_Size(argv);
5141 getitem = PyTuple_GetItem;
5142 }
5143 else {
5144 PyErr_SetString(PyExc_TypeError,
5145 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 return NULL;
5147 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005148 if (argc == 0) {
5149 PyErr_SetString(PyExc_ValueError,
5150 "spawnv() arg 2 cannot be empty");
5151 return NULL;
5152 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005153
Steve Dowercc16be82016-09-08 10:35:16 -07005154 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005156 return PyErr_NoMemory();
5157 }
5158 for (i = 0; i < argc; i++) {
5159 if (!fsconvert_strdup((*getitem)(argv, i),
5160 &argvlist[i])) {
5161 free_string_array(argvlist, i);
5162 PyErr_SetString(
5163 PyExc_TypeError,
5164 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 return NULL;
5166 }
Steve Dower93ff8722016-11-19 19:03:54 -08005167 if (i == 0 && !argvlist[0][0]) {
5168 free_string_array(argvlist, i);
5169 PyErr_SetString(
5170 PyExc_ValueError,
5171 "spawnv() arg 2 first element cannot be empty");
5172 return NULL;
5173 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 }
5175 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005176
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 if (mode == _OLD_P_OVERLAY)
5178 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005179
Victor Stinner8c62be82010-05-06 00:08:46 +00005180 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005181 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005182#ifdef HAVE_WSPAWNV
5183 spawnval = _wspawnv(mode, path->wide, argvlist);
5184#else
5185 spawnval = _spawnv(mode, path->narrow, argvlist);
5186#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005187 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005189
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005191
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 if (spawnval == -1)
5193 return posix_error();
5194 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005195 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005196}
5197
5198
Larry Hastings2f936352014-08-05 14:04:04 +10005199/*[clinic input]
5200os.spawnve
5201
5202 mode: int
5203 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005204 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005205 Path of executable file.
5206 argv: object
5207 Tuple or list of strings.
5208 env: object
5209 Dictionary of strings mapping to strings.
5210 /
5211
5212Execute the program specified by path in a new process.
5213[clinic start generated code]*/
5214
Larry Hastings2f936352014-08-05 14:04:04 +10005215static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005216os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005217 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005218/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005219{
Steve Dowercc16be82016-09-08 10:35:16 -07005220 EXECV_CHAR **argvlist;
5221 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005223 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005224 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5226 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005227
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 /* spawnve has four arguments: (mode, path, argv, env), where
5229 argv is a list or tuple of strings and env is a dictionary
5230 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005231
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 if (PyList_Check(argv)) {
5233 argc = PyList_Size(argv);
5234 getitem = PyList_GetItem;
5235 }
5236 else if (PyTuple_Check(argv)) {
5237 argc = PyTuple_Size(argv);
5238 getitem = PyTuple_GetItem;
5239 }
5240 else {
5241 PyErr_SetString(PyExc_TypeError,
5242 "spawnve() arg 2 must be a tuple or list");
5243 goto fail_0;
5244 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005245 if (argc == 0) {
5246 PyErr_SetString(PyExc_ValueError,
5247 "spawnve() arg 2 cannot be empty");
5248 goto fail_0;
5249 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005250 if (!PyMapping_Check(env)) {
5251 PyErr_SetString(PyExc_TypeError,
5252 "spawnve() arg 3 must be a mapping object");
5253 goto fail_0;
5254 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005255
Steve Dowercc16be82016-09-08 10:35:16 -07005256 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 if (argvlist == NULL) {
5258 PyErr_NoMemory();
5259 goto fail_0;
5260 }
5261 for (i = 0; i < argc; i++) {
5262 if (!fsconvert_strdup((*getitem)(argv, i),
5263 &argvlist[i]))
5264 {
5265 lastarg = i;
5266 goto fail_1;
5267 }
Steve Dowerbce26262016-11-19 19:17:26 -08005268 if (i == 0 && !argvlist[0][0]) {
5269 lastarg = i;
5270 PyErr_SetString(
5271 PyExc_ValueError,
5272 "spawnv() arg 2 first element cannot be empty");
5273 goto fail_1;
5274 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 }
5276 lastarg = argc;
5277 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005278
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 envlist = parse_envlist(env, &envc);
5280 if (envlist == NULL)
5281 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005282
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 if (mode == _OLD_P_OVERLAY)
5284 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005285
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005287 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005288#ifdef HAVE_WSPAWNV
5289 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5290#else
5291 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5292#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005293 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005295
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 if (spawnval == -1)
5297 (void) posix_error();
5298 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005299 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 while (--envc >= 0)
5302 PyMem_DEL(envlist[envc]);
5303 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005304 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005305 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005306 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005308}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005309
Guido van Rossuma1065681999-01-25 23:20:23 +00005310#endif /* HAVE_SPAWNV */
5311
5312
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005313#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005314
5315/* Helper function to validate arguments.
5316 Returns 0 on success. non-zero on failure with a TypeError raised.
5317 If obj is non-NULL it must be callable. */
5318static int
5319check_null_or_callable(PyObject *obj, const char* obj_name)
5320{
5321 if (obj && !PyCallable_Check(obj)) {
5322 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5323 obj_name, Py_TYPE(obj)->tp_name);
5324 return -1;
5325 }
5326 return 0;
5327}
5328
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005329/*[clinic input]
5330os.register_at_fork
5331
Gregory P. Smith163468a2017-05-29 10:03:41 -07005332 *
5333 before: object=NULL
5334 A callable to be called in the parent before the fork() syscall.
5335 after_in_child: object=NULL
5336 A callable to be called in the child after fork().
5337 after_in_parent: object=NULL
5338 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005339
Gregory P. Smith163468a2017-05-29 10:03:41 -07005340Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005341
Gregory P. Smith163468a2017-05-29 10:03:41 -07005342'before' callbacks are called in reverse order.
5343'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005344
5345[clinic start generated code]*/
5346
5347static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005348os_register_at_fork_impl(PyObject *module, PyObject *before,
5349 PyObject *after_in_child, PyObject *after_in_parent)
5350/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005351{
5352 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005353
Gregory P. Smith163468a2017-05-29 10:03:41 -07005354 if (!before && !after_in_child && !after_in_parent) {
5355 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5356 return NULL;
5357 }
5358 if (check_null_or_callable(before, "before") ||
5359 check_null_or_callable(after_in_child, "after_in_child") ||
5360 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005361 return NULL;
5362 }
5363 interp = PyThreadState_Get()->interp;
5364
Gregory P. Smith163468a2017-05-29 10:03:41 -07005365 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005366 return NULL;
5367 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005368 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005369 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005370 }
5371 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5372 return NULL;
5373 }
5374 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005375}
5376#endif /* HAVE_FORK */
5377
5378
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005379#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005380/*[clinic input]
5381os.fork1
5382
5383Fork a child process with a single multiplexed (i.e., not bound) thread.
5384
5385Return 0 to child process and PID of child to parent process.
5386[clinic start generated code]*/
5387
Larry Hastings2f936352014-08-05 14:04:04 +10005388static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005389os_fork1_impl(PyObject *module)
5390/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005391{
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005393
5394 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005395 pid = fork1();
5396 if (pid == 0) {
5397 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005398 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 } else {
5400 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005401 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 }
5403 if (pid == -1)
5404 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005406}
Larry Hastings2f936352014-08-05 14:04:04 +10005407#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005408
5409
Guido van Rossumad0ee831995-03-01 10:34:45 +00005410#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005411/*[clinic input]
5412os.fork
5413
5414Fork a child process.
5415
5416Return 0 to child process and PID of child to parent process.
5417[clinic start generated code]*/
5418
Larry Hastings2f936352014-08-05 14:04:04 +10005419static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005420os_fork_impl(PyObject *module)
5421/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005422{
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005424
5425 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 pid = fork();
5427 if (pid == 0) {
5428 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005429 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005430 } else {
5431 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005432 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005433 }
5434 if (pid == -1)
5435 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005437}
Larry Hastings2f936352014-08-05 14:04:04 +10005438#endif /* HAVE_FORK */
5439
Guido van Rossum85e3b011991-06-03 12:42:10 +00005440
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005441#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005442#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005443/*[clinic input]
5444os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005445
Larry Hastings2f936352014-08-05 14:04:04 +10005446 policy: int
5447
5448Get the maximum scheduling priority for policy.
5449[clinic start generated code]*/
5450
Larry Hastings2f936352014-08-05 14:04:04 +10005451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005452os_sched_get_priority_max_impl(PyObject *module, int policy)
5453/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005454{
5455 int max;
5456
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005457 max = sched_get_priority_max(policy);
5458 if (max < 0)
5459 return posix_error();
5460 return PyLong_FromLong(max);
5461}
5462
Larry Hastings2f936352014-08-05 14:04:04 +10005463
5464/*[clinic input]
5465os.sched_get_priority_min
5466
5467 policy: int
5468
5469Get the minimum scheduling priority for policy.
5470[clinic start generated code]*/
5471
Larry Hastings2f936352014-08-05 14:04:04 +10005472static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005473os_sched_get_priority_min_impl(PyObject *module, int policy)
5474/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005475{
5476 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005477 if (min < 0)
5478 return posix_error();
5479 return PyLong_FromLong(min);
5480}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005481#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5482
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005483
Larry Hastings2f936352014-08-05 14:04:04 +10005484#ifdef HAVE_SCHED_SETSCHEDULER
5485/*[clinic input]
5486os.sched_getscheduler
5487 pid: pid_t
5488 /
5489
5490Get the scheduling policy for the process identifiedy by pid.
5491
5492Passing 0 for pid returns the scheduling policy for the calling process.
5493[clinic start generated code]*/
5494
Larry Hastings2f936352014-08-05 14:04:04 +10005495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005496os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5497/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005498{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005499 int policy;
5500
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005501 policy = sched_getscheduler(pid);
5502 if (policy < 0)
5503 return posix_error();
5504 return PyLong_FromLong(policy);
5505}
Larry Hastings2f936352014-08-05 14:04:04 +10005506#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005507
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005508
5509#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005510/*[clinic input]
5511class os.sched_param "PyObject *" "&SchedParamType"
5512
5513@classmethod
5514os.sched_param.__new__
5515
5516 sched_priority: object
5517 A scheduling parameter.
5518
5519Current has only one field: sched_priority");
5520[clinic start generated code]*/
5521
Larry Hastings2f936352014-08-05 14:04:04 +10005522static PyObject *
5523os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005524/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005525{
5526 PyObject *res;
5527
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005528 res = PyStructSequence_New(type);
5529 if (!res)
5530 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005531 Py_INCREF(sched_priority);
5532 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005533 return res;
5534}
5535
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005536
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005537PyDoc_VAR(os_sched_param__doc__);
5538
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005539static PyStructSequence_Field sched_param_fields[] = {
5540 {"sched_priority", "the scheduling priority"},
5541 {0}
5542};
5543
5544static PyStructSequence_Desc sched_param_desc = {
5545 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005546 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547 sched_param_fields,
5548 1
5549};
5550
5551static int
5552convert_sched_param(PyObject *param, struct sched_param *res)
5553{
5554 long priority;
5555
5556 if (Py_TYPE(param) != &SchedParamType) {
5557 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5558 return 0;
5559 }
5560 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5561 if (priority == -1 && PyErr_Occurred())
5562 return 0;
5563 if (priority > INT_MAX || priority < INT_MIN) {
5564 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5565 return 0;
5566 }
5567 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5568 return 1;
5569}
Larry Hastings2f936352014-08-05 14:04:04 +10005570#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005572
5573#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005574/*[clinic input]
5575os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005576
Larry Hastings2f936352014-08-05 14:04:04 +10005577 pid: pid_t
5578 policy: int
5579 param: sched_param
5580 /
5581
5582Set the scheduling policy for the process identified by pid.
5583
5584If pid is 0, the calling process is changed.
5585param is an instance of sched_param.
5586[clinic start generated code]*/
5587
Larry Hastings2f936352014-08-05 14:04:04 +10005588static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005589os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005590 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005591/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005592{
Jesus Cea9c822272011-09-10 01:40:52 +02005593 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005594 ** sched_setscheduler() returns 0 in Linux, but the previous
5595 ** scheduling policy under Solaris/Illumos, and others.
5596 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005597 */
Larry Hastings2f936352014-08-05 14:04:04 +10005598 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005599 return posix_error();
5600 Py_RETURN_NONE;
5601}
Larry Hastings2f936352014-08-05 14:04:04 +10005602#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005603
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005604
5605#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005606/*[clinic input]
5607os.sched_getparam
5608 pid: pid_t
5609 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005610
Larry Hastings2f936352014-08-05 14:04:04 +10005611Returns scheduling parameters for the process identified by pid.
5612
5613If pid is 0, returns parameters for the calling process.
5614Return value is an instance of sched_param.
5615[clinic start generated code]*/
5616
Larry Hastings2f936352014-08-05 14:04:04 +10005617static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005618os_sched_getparam_impl(PyObject *module, pid_t pid)
5619/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005620{
5621 struct sched_param param;
5622 PyObject *result;
5623 PyObject *priority;
5624
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005625 if (sched_getparam(pid, &param))
5626 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005627 result = PyStructSequence_New(&SchedParamType);
5628 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005629 return NULL;
5630 priority = PyLong_FromLong(param.sched_priority);
5631 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005632 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005633 return NULL;
5634 }
Larry Hastings2f936352014-08-05 14:04:04 +10005635 PyStructSequence_SET_ITEM(result, 0, priority);
5636 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637}
5638
Larry Hastings2f936352014-08-05 14:04:04 +10005639
5640/*[clinic input]
5641os.sched_setparam
5642 pid: pid_t
5643 param: sched_param
5644 /
5645
5646Set scheduling parameters for the process identified by pid.
5647
5648If pid is 0, sets parameters for the calling process.
5649param should be an instance of sched_param.
5650[clinic start generated code]*/
5651
Larry Hastings2f936352014-08-05 14:04:04 +10005652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005653os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005654 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005655/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005656{
5657 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005658 return posix_error();
5659 Py_RETURN_NONE;
5660}
Larry Hastings2f936352014-08-05 14:04:04 +10005661#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005662
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005663
5664#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005665/*[clinic input]
5666os.sched_rr_get_interval -> double
5667 pid: pid_t
5668 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005669
Larry Hastings2f936352014-08-05 14:04:04 +10005670Return the round-robin quantum for the process identified by pid, in seconds.
5671
5672Value returned is a float.
5673[clinic start generated code]*/
5674
Larry Hastings2f936352014-08-05 14:04:04 +10005675static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005676os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5677/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005678{
5679 struct timespec interval;
5680 if (sched_rr_get_interval(pid, &interval)) {
5681 posix_error();
5682 return -1.0;
5683 }
5684 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5685}
5686#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005687
Larry Hastings2f936352014-08-05 14:04:04 +10005688
5689/*[clinic input]
5690os.sched_yield
5691
5692Voluntarily relinquish the CPU.
5693[clinic start generated code]*/
5694
Larry Hastings2f936352014-08-05 14:04:04 +10005695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005696os_sched_yield_impl(PyObject *module)
5697/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005698{
5699 if (sched_yield())
5700 return posix_error();
5701 Py_RETURN_NONE;
5702}
5703
Benjamin Peterson2740af82011-08-02 17:41:34 -05005704#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005705/* The minimum number of CPUs allocated in a cpu_set_t */
5706static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005707
Larry Hastings2f936352014-08-05 14:04:04 +10005708/*[clinic input]
5709os.sched_setaffinity
5710 pid: pid_t
5711 mask : object
5712 /
5713
5714Set the CPU affinity of the process identified by pid to mask.
5715
5716mask should be an iterable of integers identifying CPUs.
5717[clinic start generated code]*/
5718
Larry Hastings2f936352014-08-05 14:04:04 +10005719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005720os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5721/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005722{
Antoine Pitrou84869872012-08-04 16:16:35 +02005723 int ncpus;
5724 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005725 cpu_set_t *cpu_set = NULL;
5726 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005727
Larry Hastings2f936352014-08-05 14:04:04 +10005728 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005729 if (iterator == NULL)
5730 return NULL;
5731
5732 ncpus = NCPUS_START;
5733 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005734 cpu_set = CPU_ALLOC(ncpus);
5735 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005736 PyErr_NoMemory();
5737 goto error;
5738 }
Larry Hastings2f936352014-08-05 14:04:04 +10005739 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005740
5741 while ((item = PyIter_Next(iterator))) {
5742 long cpu;
5743 if (!PyLong_Check(item)) {
5744 PyErr_Format(PyExc_TypeError,
5745 "expected an iterator of ints, "
5746 "but iterator yielded %R",
5747 Py_TYPE(item));
5748 Py_DECREF(item);
5749 goto error;
5750 }
5751 cpu = PyLong_AsLong(item);
5752 Py_DECREF(item);
5753 if (cpu < 0) {
5754 if (!PyErr_Occurred())
5755 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5756 goto error;
5757 }
5758 if (cpu > INT_MAX - 1) {
5759 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5760 goto error;
5761 }
5762 if (cpu >= ncpus) {
5763 /* Grow CPU mask to fit the CPU number */
5764 int newncpus = ncpus;
5765 cpu_set_t *newmask;
5766 size_t newsetsize;
5767 while (newncpus <= cpu) {
5768 if (newncpus > INT_MAX / 2)
5769 newncpus = cpu + 1;
5770 else
5771 newncpus = newncpus * 2;
5772 }
5773 newmask = CPU_ALLOC(newncpus);
5774 if (newmask == NULL) {
5775 PyErr_NoMemory();
5776 goto error;
5777 }
5778 newsetsize = CPU_ALLOC_SIZE(newncpus);
5779 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005780 memcpy(newmask, cpu_set, setsize);
5781 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005782 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005783 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005784 ncpus = newncpus;
5785 }
Larry Hastings2f936352014-08-05 14:04:04 +10005786 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005787 }
5788 Py_CLEAR(iterator);
5789
Larry Hastings2f936352014-08-05 14:04:04 +10005790 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005791 posix_error();
5792 goto error;
5793 }
Larry Hastings2f936352014-08-05 14:04:04 +10005794 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005795 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005796
5797error:
Larry Hastings2f936352014-08-05 14:04:04 +10005798 if (cpu_set)
5799 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005800 Py_XDECREF(iterator);
5801 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005802}
5803
Larry Hastings2f936352014-08-05 14:04:04 +10005804
5805/*[clinic input]
5806os.sched_getaffinity
5807 pid: pid_t
5808 /
5809
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005810Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005811
5812The affinity is returned as a set of CPU identifiers.
5813[clinic start generated code]*/
5814
Larry Hastings2f936352014-08-05 14:04:04 +10005815static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005816os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005817/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005818{
Antoine Pitrou84869872012-08-04 16:16:35 +02005819 int cpu, ncpus, count;
5820 size_t setsize;
5821 cpu_set_t *mask = NULL;
5822 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005823
Antoine Pitrou84869872012-08-04 16:16:35 +02005824 ncpus = NCPUS_START;
5825 while (1) {
5826 setsize = CPU_ALLOC_SIZE(ncpus);
5827 mask = CPU_ALLOC(ncpus);
5828 if (mask == NULL)
5829 return PyErr_NoMemory();
5830 if (sched_getaffinity(pid, setsize, mask) == 0)
5831 break;
5832 CPU_FREE(mask);
5833 if (errno != EINVAL)
5834 return posix_error();
5835 if (ncpus > INT_MAX / 2) {
5836 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5837 "a large enough CPU set");
5838 return NULL;
5839 }
5840 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005841 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005842
5843 res = PySet_New(NULL);
5844 if (res == NULL)
5845 goto error;
5846 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5847 if (CPU_ISSET_S(cpu, setsize, mask)) {
5848 PyObject *cpu_num = PyLong_FromLong(cpu);
5849 --count;
5850 if (cpu_num == NULL)
5851 goto error;
5852 if (PySet_Add(res, cpu_num)) {
5853 Py_DECREF(cpu_num);
5854 goto error;
5855 }
5856 Py_DECREF(cpu_num);
5857 }
5858 }
5859 CPU_FREE(mask);
5860 return res;
5861
5862error:
5863 if (mask)
5864 CPU_FREE(mask);
5865 Py_XDECREF(res);
5866 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005867}
5868
Benjamin Peterson2740af82011-08-02 17:41:34 -05005869#endif /* HAVE_SCHED_SETAFFINITY */
5870
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005871#endif /* HAVE_SCHED_H */
5872
Larry Hastings2f936352014-08-05 14:04:04 +10005873
Neal Norwitzb59798b2003-03-21 01:43:31 +00005874/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005875/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5876#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005877#define DEV_PTY_FILE "/dev/ptc"
5878#define HAVE_DEV_PTMX
5879#else
5880#define DEV_PTY_FILE "/dev/ptmx"
5881#endif
5882
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005883#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005884#ifdef HAVE_PTY_H
5885#include <pty.h>
5886#else
5887#ifdef HAVE_LIBUTIL_H
5888#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005889#else
5890#ifdef HAVE_UTIL_H
5891#include <util.h>
5892#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005893#endif /* HAVE_LIBUTIL_H */
5894#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005895#ifdef HAVE_STROPTS_H
5896#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005897#endif
5898#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005899
Larry Hastings2f936352014-08-05 14:04:04 +10005900
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005901#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005902/*[clinic input]
5903os.openpty
5904
5905Open a pseudo-terminal.
5906
5907Return a tuple of (master_fd, slave_fd) containing open file descriptors
5908for both the master and slave ends.
5909[clinic start generated code]*/
5910
Larry Hastings2f936352014-08-05 14:04:04 +10005911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005912os_openpty_impl(PyObject *module)
5913/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005914{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005915 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005916#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005918#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005919#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005921#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005923#endif
5924#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005925
Thomas Wouters70c21a12000-07-14 14:28:33 +00005926#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005928 goto posix_error;
5929
5930 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5931 goto error;
5932 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5933 goto error;
5934
Neal Norwitzb59798b2003-03-21 01:43:31 +00005935#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5937 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005938 goto posix_error;
5939 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5940 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941
Victor Stinnerdaf45552013-08-28 00:53:59 +02005942 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005944 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005945
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005946#else
Victor Stinner000de532013-11-25 23:19:58 +01005947 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005949 goto posix_error;
5950
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005952
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 /* change permission of slave */
5954 if (grantpt(master_fd) < 0) {
5955 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005956 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005957 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005958
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 /* unlock slave */
5960 if (unlockpt(master_fd) < 0) {
5961 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005962 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005966
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 slave_name = ptsname(master_fd); /* get name of slave */
5968 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005969 goto posix_error;
5970
5971 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005972 if (slave_fd == -1)
5973 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005974
5975 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5976 goto posix_error;
5977
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005978#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5980 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005981#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005983#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005984#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005985#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005986
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005988
Victor Stinnerdaf45552013-08-28 00:53:59 +02005989posix_error:
5990 posix_error();
5991error:
5992 if (master_fd != -1)
5993 close(master_fd);
5994 if (slave_fd != -1)
5995 close(slave_fd);
5996 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005997}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005998#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005999
Larry Hastings2f936352014-08-05 14:04:04 +10006000
Fred Drake8cef4cf2000-06-28 16:40:38 +00006001#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006002/*[clinic input]
6003os.forkpty
6004
6005Fork a new process with a new pseudo-terminal as controlling tty.
6006
6007Returns a tuple of (pid, master_fd).
6008Like fork(), return pid of 0 to the child process,
6009and pid of child to the parent process.
6010To both, return fd of newly opened pseudo-terminal.
6011[clinic start generated code]*/
6012
Larry Hastings2f936352014-08-05 14:04:04 +10006013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006014os_forkpty_impl(PyObject *module)
6015/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006016{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006017 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006019
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006020 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 pid = forkpty(&master_fd, NULL, NULL, NULL);
6022 if (pid == 0) {
6023 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006024 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 } else {
6026 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006027 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 }
6029 if (pid == -1)
6030 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006032}
Larry Hastings2f936352014-08-05 14:04:04 +10006033#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006034
Ross Lagerwall7807c352011-03-17 20:20:30 +02006035
Guido van Rossumad0ee831995-03-01 10:34:45 +00006036#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006037/*[clinic input]
6038os.getegid
6039
6040Return the current process's effective group id.
6041[clinic start generated code]*/
6042
Larry Hastings2f936352014-08-05 14:04:04 +10006043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006044os_getegid_impl(PyObject *module)
6045/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006046{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006047 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006048}
Larry Hastings2f936352014-08-05 14:04:04 +10006049#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006050
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006051
Guido van Rossumad0ee831995-03-01 10:34:45 +00006052#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006053/*[clinic input]
6054os.geteuid
6055
6056Return the current process's effective user id.
6057[clinic start generated code]*/
6058
Larry Hastings2f936352014-08-05 14:04:04 +10006059static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006060os_geteuid_impl(PyObject *module)
6061/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006062{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006063 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006064}
Larry Hastings2f936352014-08-05 14:04:04 +10006065#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006067
Guido van Rossumad0ee831995-03-01 10:34:45 +00006068#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006069/*[clinic input]
6070os.getgid
6071
6072Return the current process's group id.
6073[clinic start generated code]*/
6074
Larry Hastings2f936352014-08-05 14:04:04 +10006075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006076os_getgid_impl(PyObject *module)
6077/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006078{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006079 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006080}
Larry Hastings2f936352014-08-05 14:04:04 +10006081#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006083
Berker Peksag39404992016-09-15 20:45:16 +03006084#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006085/*[clinic input]
6086os.getpid
6087
6088Return the current process id.
6089[clinic start generated code]*/
6090
Larry Hastings2f936352014-08-05 14:04:04 +10006091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006092os_getpid_impl(PyObject *module)
6093/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006094{
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006096}
Berker Peksag39404992016-09-15 20:45:16 +03006097#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006098
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006099#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006100
6101/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006102PyDoc_STRVAR(posix_getgrouplist__doc__,
6103"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6104Returns a list of groups to which a user belongs.\n\n\
6105 user: username to lookup\n\
6106 group: base group id of the user");
6107
6108static PyObject *
6109posix_getgrouplist(PyObject *self, PyObject *args)
6110{
6111#ifdef NGROUPS_MAX
6112#define MAX_GROUPS NGROUPS_MAX
6113#else
6114 /* defined to be 16 on Solaris7, so this should be a small number */
6115#define MAX_GROUPS 64
6116#endif
6117
6118 const char *user;
6119 int i, ngroups;
6120 PyObject *list;
6121#ifdef __APPLE__
6122 int *groups, basegid;
6123#else
6124 gid_t *groups, basegid;
6125#endif
6126 ngroups = MAX_GROUPS;
6127
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006128#ifdef __APPLE__
6129 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006130 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006131#else
6132 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6133 _Py_Gid_Converter, &basegid))
6134 return NULL;
6135#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006136
6137#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006138 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006139#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006140 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006141#endif
6142 if (groups == NULL)
6143 return PyErr_NoMemory();
6144
6145 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6146 PyMem_Del(groups);
6147 return posix_error();
6148 }
6149
6150 list = PyList_New(ngroups);
6151 if (list == NULL) {
6152 PyMem_Del(groups);
6153 return NULL;
6154 }
6155
6156 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006157#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006158 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006159#else
6160 PyObject *o = _PyLong_FromGid(groups[i]);
6161#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006162 if (o == NULL) {
6163 Py_DECREF(list);
6164 PyMem_Del(groups);
6165 return NULL;
6166 }
6167 PyList_SET_ITEM(list, i, o);
6168 }
6169
6170 PyMem_Del(groups);
6171
6172 return list;
6173}
Larry Hastings2f936352014-08-05 14:04:04 +10006174#endif /* HAVE_GETGROUPLIST */
6175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006176
Fred Drakec9680921999-12-13 16:37:25 +00006177#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006178/*[clinic input]
6179os.getgroups
6180
6181Return list of supplemental group IDs for the process.
6182[clinic start generated code]*/
6183
Larry Hastings2f936352014-08-05 14:04:04 +10006184static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006185os_getgroups_impl(PyObject *module)
6186/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006187{
6188 PyObject *result = NULL;
6189
Fred Drakec9680921999-12-13 16:37:25 +00006190#ifdef NGROUPS_MAX
6191#define MAX_GROUPS NGROUPS_MAX
6192#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006193 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006194#define MAX_GROUPS 64
6195#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006197
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006198 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006199 * This is a helper variable to store the intermediate result when
6200 * that happens.
6201 *
6202 * To keep the code readable the OSX behaviour is unconditional,
6203 * according to the POSIX spec this should be safe on all unix-y
6204 * systems.
6205 */
6206 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006208
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006209#ifdef __APPLE__
6210 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6211 * there are more groups than can fit in grouplist. Therefore, on OS X
6212 * always first call getgroups with length 0 to get the actual number
6213 * of groups.
6214 */
6215 n = getgroups(0, NULL);
6216 if (n < 0) {
6217 return posix_error();
6218 } else if (n <= MAX_GROUPS) {
6219 /* groups will fit in existing array */
6220 alt_grouplist = grouplist;
6221 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006222 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006223 if (alt_grouplist == NULL) {
6224 errno = EINVAL;
6225 return posix_error();
6226 }
6227 }
6228
6229 n = getgroups(n, alt_grouplist);
6230 if (n == -1) {
6231 if (alt_grouplist != grouplist) {
6232 PyMem_Free(alt_grouplist);
6233 }
6234 return posix_error();
6235 }
6236#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006238 if (n < 0) {
6239 if (errno == EINVAL) {
6240 n = getgroups(0, NULL);
6241 if (n == -1) {
6242 return posix_error();
6243 }
6244 if (n == 0) {
6245 /* Avoid malloc(0) */
6246 alt_grouplist = grouplist;
6247 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006248 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006249 if (alt_grouplist == NULL) {
6250 errno = EINVAL;
6251 return posix_error();
6252 }
6253 n = getgroups(n, alt_grouplist);
6254 if (n == -1) {
6255 PyMem_Free(alt_grouplist);
6256 return posix_error();
6257 }
6258 }
6259 } else {
6260 return posix_error();
6261 }
6262 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006263#endif
6264
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006265 result = PyList_New(n);
6266 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 int i;
6268 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006269 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006271 Py_DECREF(result);
6272 result = NULL;
6273 break;
Fred Drakec9680921999-12-13 16:37:25 +00006274 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006276 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006277 }
6278
6279 if (alt_grouplist != grouplist) {
6280 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006282
Fred Drakec9680921999-12-13 16:37:25 +00006283 return result;
6284}
Larry Hastings2f936352014-08-05 14:04:04 +10006285#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006286
Antoine Pitroub7572f02009-12-02 20:46:48 +00006287#ifdef HAVE_INITGROUPS
6288PyDoc_STRVAR(posix_initgroups__doc__,
6289"initgroups(username, gid) -> None\n\n\
6290Call the system initgroups() to initialize the group access list with all of\n\
6291the groups of which the specified username is a member, plus the specified\n\
6292group id.");
6293
Larry Hastings2f936352014-08-05 14:04:04 +10006294/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006295static PyObject *
6296posix_initgroups(PyObject *self, PyObject *args)
6297{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006298 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006299 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006300 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006301#ifdef __APPLE__
6302 int gid;
6303#else
6304 gid_t gid;
6305#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006306
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006307#ifdef __APPLE__
6308 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6309 PyUnicode_FSConverter, &oname,
6310 &gid))
6311#else
6312 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6313 PyUnicode_FSConverter, &oname,
6314 _Py_Gid_Converter, &gid))
6315#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006317 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006318
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006319 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006320 Py_DECREF(oname);
6321 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006323
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006324 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006325}
Larry Hastings2f936352014-08-05 14:04:04 +10006326#endif /* HAVE_INITGROUPS */
6327
Antoine Pitroub7572f02009-12-02 20:46:48 +00006328
Martin v. Löwis606edc12002-06-13 21:09:11 +00006329#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006330/*[clinic input]
6331os.getpgid
6332
6333 pid: pid_t
6334
6335Call the system call getpgid(), and return the result.
6336[clinic start generated code]*/
6337
Larry Hastings2f936352014-08-05 14:04:04 +10006338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006339os_getpgid_impl(PyObject *module, pid_t pid)
6340/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006341{
6342 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 if (pgid < 0)
6344 return posix_error();
6345 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006346}
6347#endif /* HAVE_GETPGID */
6348
6349
Guido van Rossumb6775db1994-08-01 11:34:53 +00006350#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006351/*[clinic input]
6352os.getpgrp
6353
6354Return the current process group id.
6355[clinic start generated code]*/
6356
Larry Hastings2f936352014-08-05 14:04:04 +10006357static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006358os_getpgrp_impl(PyObject *module)
6359/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006360{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006363#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006365#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006366}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006367#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006369
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006371/*[clinic input]
6372os.setpgrp
6373
6374Make the current process the leader of its process group.
6375[clinic start generated code]*/
6376
Larry Hastings2f936352014-08-05 14:04:04 +10006377static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006378os_setpgrp_impl(PyObject *module)
6379/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006380{
Guido van Rossum64933891994-10-20 21:56:42 +00006381#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006383#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006385#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006387 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006388}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006389#endif /* HAVE_SETPGRP */
6390
Guido van Rossumad0ee831995-03-01 10:34:45 +00006391#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006392
6393#ifdef MS_WINDOWS
6394#include <tlhelp32.h>
6395
6396static PyObject*
6397win32_getppid()
6398{
6399 HANDLE snapshot;
6400 pid_t mypid;
6401 PyObject* result = NULL;
6402 BOOL have_record;
6403 PROCESSENTRY32 pe;
6404
6405 mypid = getpid(); /* This function never fails */
6406
6407 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6408 if (snapshot == INVALID_HANDLE_VALUE)
6409 return PyErr_SetFromWindowsErr(GetLastError());
6410
6411 pe.dwSize = sizeof(pe);
6412 have_record = Process32First(snapshot, &pe);
6413 while (have_record) {
6414 if (mypid == (pid_t)pe.th32ProcessID) {
6415 /* We could cache the ulong value in a static variable. */
6416 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6417 break;
6418 }
6419
6420 have_record = Process32Next(snapshot, &pe);
6421 }
6422
6423 /* If our loop exits and our pid was not found (result will be NULL)
6424 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6425 * error anyway, so let's raise it. */
6426 if (!result)
6427 result = PyErr_SetFromWindowsErr(GetLastError());
6428
6429 CloseHandle(snapshot);
6430
6431 return result;
6432}
6433#endif /*MS_WINDOWS*/
6434
Larry Hastings2f936352014-08-05 14:04:04 +10006435
6436/*[clinic input]
6437os.getppid
6438
6439Return the parent's process id.
6440
6441If the parent process has already exited, Windows machines will still
6442return its id; others systems will return the id of the 'init' process (1).
6443[clinic start generated code]*/
6444
Larry Hastings2f936352014-08-05 14:04:04 +10006445static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006446os_getppid_impl(PyObject *module)
6447/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006448{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006449#ifdef MS_WINDOWS
6450 return win32_getppid();
6451#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006453#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006454}
6455#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006457
Fred Drake12c6e2d1999-12-14 21:25:03 +00006458#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006459/*[clinic input]
6460os.getlogin
6461
6462Return the actual login name.
6463[clinic start generated code]*/
6464
Larry Hastings2f936352014-08-05 14:04:04 +10006465static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006466os_getlogin_impl(PyObject *module)
6467/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006468{
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006470#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006471 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006472 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006473
6474 if (GetUserNameW(user_name, &num_chars)) {
6475 /* num_chars is the number of unicode chars plus null terminator */
6476 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006477 }
6478 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006479 result = PyErr_SetFromWindowsErr(GetLastError());
6480#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 char *name;
6482 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006483
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 errno = 0;
6485 name = getlogin();
6486 if (name == NULL) {
6487 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006488 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006489 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006490 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 }
6492 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006493 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006495#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006496 return result;
6497}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006498#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006499
Larry Hastings2f936352014-08-05 14:04:04 +10006500
Guido van Rossumad0ee831995-03-01 10:34:45 +00006501#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006502/*[clinic input]
6503os.getuid
6504
6505Return the current process's user id.
6506[clinic start generated code]*/
6507
Larry Hastings2f936352014-08-05 14:04:04 +10006508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006509os_getuid_impl(PyObject *module)
6510/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006511{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006512 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006513}
Larry Hastings2f936352014-08-05 14:04:04 +10006514#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006516
Brian Curtineb24d742010-04-12 17:16:38 +00006517#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006518#define HAVE_KILL
6519#endif /* MS_WINDOWS */
6520
6521#ifdef HAVE_KILL
6522/*[clinic input]
6523os.kill
6524
6525 pid: pid_t
6526 signal: Py_ssize_t
6527 /
6528
6529Kill a process with a signal.
6530[clinic start generated code]*/
6531
Larry Hastings2f936352014-08-05 14:04:04 +10006532static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006533os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6534/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006535#ifndef MS_WINDOWS
6536{
6537 if (kill(pid, (int)signal) == -1)
6538 return posix_error();
6539 Py_RETURN_NONE;
6540}
6541#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006542{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006543 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006544 DWORD sig = (DWORD)signal;
6545 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006547
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 /* Console processes which share a common console can be sent CTRL+C or
6549 CTRL+BREAK events, provided they handle said events. */
6550 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006551 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 err = GetLastError();
6553 PyErr_SetFromWindowsErr(err);
6554 }
6555 else
6556 Py_RETURN_NONE;
6557 }
Brian Curtineb24d742010-04-12 17:16:38 +00006558
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6560 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006561 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 if (handle == NULL) {
6563 err = GetLastError();
6564 return PyErr_SetFromWindowsErr(err);
6565 }
Brian Curtineb24d742010-04-12 17:16:38 +00006566
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 if (TerminateProcess(handle, sig) == 0) {
6568 err = GetLastError();
6569 result = PyErr_SetFromWindowsErr(err);
6570 } else {
6571 Py_INCREF(Py_None);
6572 result = Py_None;
6573 }
Brian Curtineb24d742010-04-12 17:16:38 +00006574
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 CloseHandle(handle);
6576 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006577}
Larry Hastings2f936352014-08-05 14:04:04 +10006578#endif /* !MS_WINDOWS */
6579#endif /* HAVE_KILL */
6580
6581
6582#ifdef HAVE_KILLPG
6583/*[clinic input]
6584os.killpg
6585
6586 pgid: pid_t
6587 signal: int
6588 /
6589
6590Kill a process group with a signal.
6591[clinic start generated code]*/
6592
Larry Hastings2f936352014-08-05 14:04:04 +10006593static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006594os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6595/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006596{
6597 /* XXX some man pages make the `pgid` parameter an int, others
6598 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6599 take the same type. Moreover, pid_t is always at least as wide as
6600 int (else compilation of this module fails), which is safe. */
6601 if (killpg(pgid, signal) == -1)
6602 return posix_error();
6603 Py_RETURN_NONE;
6604}
6605#endif /* HAVE_KILLPG */
6606
Brian Curtineb24d742010-04-12 17:16:38 +00006607
Guido van Rossumc0125471996-06-28 18:55:32 +00006608#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006609#ifdef HAVE_SYS_LOCK_H
6610#include <sys/lock.h>
6611#endif
6612
Larry Hastings2f936352014-08-05 14:04:04 +10006613/*[clinic input]
6614os.plock
6615 op: int
6616 /
6617
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006618Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006619[clinic start generated code]*/
6620
Larry Hastings2f936352014-08-05 14:04:04 +10006621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006622os_plock_impl(PyObject *module, int op)
6623/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006624{
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 if (plock(op) == -1)
6626 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006627 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006628}
Larry Hastings2f936352014-08-05 14:04:04 +10006629#endif /* HAVE_PLOCK */
6630
Guido van Rossumc0125471996-06-28 18:55:32 +00006631
Guido van Rossumb6775db1994-08-01 11:34:53 +00006632#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006633/*[clinic input]
6634os.setuid
6635
6636 uid: uid_t
6637 /
6638
6639Set the current process's user id.
6640[clinic start generated code]*/
6641
Larry Hastings2f936352014-08-05 14:04:04 +10006642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006643os_setuid_impl(PyObject *module, uid_t uid)
6644/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006645{
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 if (setuid(uid) < 0)
6647 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006648 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006649}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006650#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006651
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006652
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006653#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006654/*[clinic input]
6655os.seteuid
6656
6657 euid: uid_t
6658 /
6659
6660Set the current process's effective user id.
6661[clinic start generated code]*/
6662
Larry Hastings2f936352014-08-05 14:04:04 +10006663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006664os_seteuid_impl(PyObject *module, uid_t euid)
6665/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006666{
6667 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006669 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006670}
6671#endif /* HAVE_SETEUID */
6672
Larry Hastings2f936352014-08-05 14:04:04 +10006673
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006674#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006675/*[clinic input]
6676os.setegid
6677
6678 egid: gid_t
6679 /
6680
6681Set the current process's effective group id.
6682[clinic start generated code]*/
6683
Larry Hastings2f936352014-08-05 14:04:04 +10006684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006685os_setegid_impl(PyObject *module, gid_t egid)
6686/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006687{
6688 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006690 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006691}
6692#endif /* HAVE_SETEGID */
6693
Larry Hastings2f936352014-08-05 14:04:04 +10006694
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006695#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006696/*[clinic input]
6697os.setreuid
6698
6699 ruid: uid_t
6700 euid: uid_t
6701 /
6702
6703Set the current process's real and effective user ids.
6704[clinic start generated code]*/
6705
Larry Hastings2f936352014-08-05 14:04:04 +10006706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006707os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6708/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006709{
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 if (setreuid(ruid, euid) < 0) {
6711 return posix_error();
6712 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006713 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006715}
6716#endif /* HAVE_SETREUID */
6717
Larry Hastings2f936352014-08-05 14:04:04 +10006718
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006719#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006720/*[clinic input]
6721os.setregid
6722
6723 rgid: gid_t
6724 egid: gid_t
6725 /
6726
6727Set the current process's real and effective group ids.
6728[clinic start generated code]*/
6729
Larry Hastings2f936352014-08-05 14:04:04 +10006730static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006731os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6732/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006733{
6734 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006736 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006737}
6738#endif /* HAVE_SETREGID */
6739
Larry Hastings2f936352014-08-05 14:04:04 +10006740
Guido van Rossumb6775db1994-08-01 11:34:53 +00006741#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006742/*[clinic input]
6743os.setgid
6744 gid: gid_t
6745 /
6746
6747Set the current process's group id.
6748[clinic start generated code]*/
6749
Larry Hastings2f936352014-08-05 14:04:04 +10006750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006751os_setgid_impl(PyObject *module, gid_t gid)
6752/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006753{
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 if (setgid(gid) < 0)
6755 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006756 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006757}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006758#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006759
Larry Hastings2f936352014-08-05 14:04:04 +10006760
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006761#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006762/*[clinic input]
6763os.setgroups
6764
6765 groups: object
6766 /
6767
6768Set the groups of the current process to list.
6769[clinic start generated code]*/
6770
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006771static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006772os_setgroups(PyObject *module, PyObject *groups)
6773/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006774{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006775 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006777
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 if (!PySequence_Check(groups)) {
6779 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6780 return NULL;
6781 }
6782 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006783 if (len < 0) {
6784 return NULL;
6785 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 if (len > MAX_GROUPS) {
6787 PyErr_SetString(PyExc_ValueError, "too many groups");
6788 return NULL;
6789 }
6790 for(i = 0; i < len; i++) {
6791 PyObject *elem;
6792 elem = PySequence_GetItem(groups, i);
6793 if (!elem)
6794 return NULL;
6795 if (!PyLong_Check(elem)) {
6796 PyErr_SetString(PyExc_TypeError,
6797 "groups must be integers");
6798 Py_DECREF(elem);
6799 return NULL;
6800 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006801 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 Py_DECREF(elem);
6803 return NULL;
6804 }
6805 }
6806 Py_DECREF(elem);
6807 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006808
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 if (setgroups(len, grouplist) < 0)
6810 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006811 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006812}
6813#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006814
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6816static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006817wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818{
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 PyObject *result;
6820 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006821 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006822
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 if (pid == -1)
6824 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 if (struct_rusage == NULL) {
6827 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6828 if (m == NULL)
6829 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006830 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 Py_DECREF(m);
6832 if (struct_rusage == NULL)
6833 return NULL;
6834 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6837 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6838 if (!result)
6839 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006840
6841#ifndef doubletime
6842#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6843#endif
6844
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006846 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006848 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6851 SET_INT(result, 2, ru->ru_maxrss);
6852 SET_INT(result, 3, ru->ru_ixrss);
6853 SET_INT(result, 4, ru->ru_idrss);
6854 SET_INT(result, 5, ru->ru_isrss);
6855 SET_INT(result, 6, ru->ru_minflt);
6856 SET_INT(result, 7, ru->ru_majflt);
6857 SET_INT(result, 8, ru->ru_nswap);
6858 SET_INT(result, 9, ru->ru_inblock);
6859 SET_INT(result, 10, ru->ru_oublock);
6860 SET_INT(result, 11, ru->ru_msgsnd);
6861 SET_INT(result, 12, ru->ru_msgrcv);
6862 SET_INT(result, 13, ru->ru_nsignals);
6863 SET_INT(result, 14, ru->ru_nvcsw);
6864 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865#undef SET_INT
6866
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 if (PyErr_Occurred()) {
6868 Py_DECREF(result);
6869 return NULL;
6870 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006871
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873}
6874#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6875
Larry Hastings2f936352014-08-05 14:04:04 +10006876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006878/*[clinic input]
6879os.wait3
6880
6881 options: int
6882Wait for completion of a child process.
6883
6884Returns a tuple of information about the child process:
6885 (pid, status, rusage)
6886[clinic start generated code]*/
6887
Larry Hastings2f936352014-08-05 14:04:04 +10006888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006889os_wait3_impl(PyObject *module, int options)
6890/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891{
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006894 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 WAIT_TYPE status;
6896 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006897
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006898 do {
6899 Py_BEGIN_ALLOW_THREADS
6900 pid = wait3(&status, options, &ru);
6901 Py_END_ALLOW_THREADS
6902 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6903 if (pid < 0)
6904 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006905
Victor Stinner4195b5c2012-02-08 23:03:19 +01006906 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907}
6908#endif /* HAVE_WAIT3 */
6909
Larry Hastings2f936352014-08-05 14:04:04 +10006910
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006912/*[clinic input]
6913
6914os.wait4
6915
6916 pid: pid_t
6917 options: int
6918
6919Wait for completion of a specific child process.
6920
6921Returns a tuple of information about the child process:
6922 (pid, status, rusage)
6923[clinic start generated code]*/
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006926os_wait4_impl(PyObject *module, pid_t pid, int options)
6927/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006928{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006929 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006931 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 WAIT_TYPE status;
6933 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 do {
6936 Py_BEGIN_ALLOW_THREADS
6937 res = wait4(pid, &status, options, &ru);
6938 Py_END_ALLOW_THREADS
6939 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6940 if (res < 0)
6941 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006942
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006943 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006944}
6945#endif /* HAVE_WAIT4 */
6946
Larry Hastings2f936352014-08-05 14:04:04 +10006947
Ross Lagerwall7807c352011-03-17 20:20:30 +02006948#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006949/*[clinic input]
6950os.waitid
6951
6952 idtype: idtype_t
6953 Must be one of be P_PID, P_PGID or P_ALL.
6954 id: id_t
6955 The id to wait on.
6956 options: int
6957 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6958 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6959 /
6960
6961Returns the result of waiting for a process or processes.
6962
6963Returns either waitid_result or None if WNOHANG is specified and there are
6964no children in a waitable state.
6965[clinic start generated code]*/
6966
Larry Hastings2f936352014-08-05 14:04:04 +10006967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006968os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6969/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006970{
6971 PyObject *result;
6972 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006973 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006974 siginfo_t si;
6975 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006976
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006977 do {
6978 Py_BEGIN_ALLOW_THREADS
6979 res = waitid(idtype, id, &si, options);
6980 Py_END_ALLOW_THREADS
6981 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6982 if (res < 0)
6983 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006984
6985 if (si.si_pid == 0)
6986 Py_RETURN_NONE;
6987
6988 result = PyStructSequence_New(&WaitidResultType);
6989 if (!result)
6990 return NULL;
6991
6992 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006993 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006994 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6995 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6996 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6997 if (PyErr_Occurred()) {
6998 Py_DECREF(result);
6999 return NULL;
7000 }
7001
7002 return result;
7003}
Larry Hastings2f936352014-08-05 14:04:04 +10007004#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007005
Larry Hastings2f936352014-08-05 14:04:04 +10007006
7007#if defined(HAVE_WAITPID)
7008/*[clinic input]
7009os.waitpid
7010 pid: pid_t
7011 options: int
7012 /
7013
7014Wait for completion of a given child process.
7015
7016Returns a tuple of information regarding the child process:
7017 (pid, status)
7018
7019The options argument is ignored on Windows.
7020[clinic start generated code]*/
7021
Larry Hastings2f936352014-08-05 14:04:04 +10007022static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007023os_waitpid_impl(PyObject *module, pid_t pid, int options)
7024/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007025{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007026 pid_t res;
7027 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 WAIT_TYPE status;
7029 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007030
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007031 do {
7032 Py_BEGIN_ALLOW_THREADS
7033 res = waitpid(pid, &status, options);
7034 Py_END_ALLOW_THREADS
7035 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7036 if (res < 0)
7037 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007038
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007039 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007040}
Tim Petersab034fa2002-02-01 11:27:43 +00007041#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007042/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007043/*[clinic input]
7044os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007045 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007046 options: int
7047 /
7048
7049Wait for completion of a given process.
7050
7051Returns a tuple of information regarding the process:
7052 (pid, status << 8)
7053
7054The options argument is ignored on Windows.
7055[clinic start generated code]*/
7056
Larry Hastings2f936352014-08-05 14:04:04 +10007057static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007058os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007059/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007060{
7061 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007062 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007063 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007064
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007065 do {
7066 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007067 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007068 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007069 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007070 Py_END_ALLOW_THREADS
7071 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007072 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007073 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007074
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007076 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007077}
Larry Hastings2f936352014-08-05 14:04:04 +10007078#endif
7079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007080
Guido van Rossumad0ee831995-03-01 10:34:45 +00007081#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007082/*[clinic input]
7083os.wait
7084
7085Wait for completion of a child process.
7086
7087Returns a tuple of information about the child process:
7088 (pid, status)
7089[clinic start generated code]*/
7090
Larry Hastings2f936352014-08-05 14:04:04 +10007091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007092os_wait_impl(PyObject *module)
7093/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007094{
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007096 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 WAIT_TYPE status;
7098 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007099
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007100 do {
7101 Py_BEGIN_ALLOW_THREADS
7102 pid = wait(&status);
7103 Py_END_ALLOW_THREADS
7104 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7105 if (pid < 0)
7106 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007107
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007109}
Larry Hastings2f936352014-08-05 14:04:04 +10007110#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007112
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7114PyDoc_STRVAR(readlink__doc__,
7115"readlink(path, *, dir_fd=None) -> path\n\n\
7116Return a string representing the path to which the symbolic link points.\n\
7117\n\
7118If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7119 and path should be relative; path will then be relative to that directory.\n\
7120dir_fd may not be implemented on your platform.\n\
7121 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007122#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007123
Guido van Rossumb6775db1994-08-01 11:34:53 +00007124#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007125
Larry Hastings2f936352014-08-05 14:04:04 +10007126/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007127static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007129{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130 path_t path;
7131 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007132 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133 ssize_t length;
7134 PyObject *return_value = NULL;
7135 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007136
Larry Hastings9cf065c2012-06-22 16:30:09 -07007137 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007138 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007139 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7140 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007141 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007143
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007145#ifdef HAVE_READLINKAT
7146 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007147 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007148 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007149#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007150 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007151 Py_END_ALLOW_THREADS
7152
7153 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007154 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155 goto exit;
7156 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007157 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007158
7159 if (PyUnicode_Check(path.object))
7160 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7161 else
7162 return_value = PyBytes_FromStringAndSize(buffer, length);
7163exit:
7164 path_cleanup(&path);
7165 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007166}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007167
Guido van Rossumb6775db1994-08-01 11:34:53 +00007168#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007169
Larry Hastings2f936352014-08-05 14:04:04 +10007170#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7171
7172static PyObject *
7173win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7174{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007175 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007176 DWORD n_bytes_returned;
7177 DWORD io_result;
7178 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007179 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007180 HANDLE reparse_point_handle;
7181
Martin Panter70214ad2016-08-04 02:38:59 +00007182 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7183 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007184 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007185
7186 static char *keywords[] = {"path", "dir_fd", NULL};
7187
7188 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7189 &po,
7190 dir_fd_unavailable, &dir_fd
7191 ))
7192 return NULL;
7193
7194 path = PyUnicode_AsUnicode(po);
7195 if (path == NULL)
7196 return NULL;
7197
7198 /* First get a handle to the reparse point */
7199 Py_BEGIN_ALLOW_THREADS
7200 reparse_point_handle = CreateFileW(
7201 path,
7202 0,
7203 0,
7204 0,
7205 OPEN_EXISTING,
7206 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7207 0);
7208 Py_END_ALLOW_THREADS
7209
7210 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7211 return win32_error_object("readlink", po);
7212
7213 Py_BEGIN_ALLOW_THREADS
7214 /* New call DeviceIoControl to read the reparse point */
7215 io_result = DeviceIoControl(
7216 reparse_point_handle,
7217 FSCTL_GET_REPARSE_POINT,
7218 0, 0, /* in buffer */
7219 target_buffer, sizeof(target_buffer),
7220 &n_bytes_returned,
7221 0 /* we're not using OVERLAPPED_IO */
7222 );
7223 CloseHandle(reparse_point_handle);
7224 Py_END_ALLOW_THREADS
7225
7226 if (io_result==0)
7227 return win32_error_object("readlink", po);
7228
7229 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7230 {
7231 PyErr_SetString(PyExc_ValueError,
7232 "not a symbolic link");
7233 return NULL;
7234 }
7235 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7236 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7237
7238 result = PyUnicode_FromWideChar(print_name,
7239 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7240 return result;
7241}
7242
7243#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7244
7245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007246
Larry Hastings9cf065c2012-06-22 16:30:09 -07007247#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007248
7249#if defined(MS_WINDOWS)
7250
7251/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007252static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007253
Larry Hastings9cf065c2012-06-22 16:30:09 -07007254static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007255check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007256{
7257 HINSTANCE hKernel32;
7258 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007259 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007260 return 1;
7261 hKernel32 = GetModuleHandleW(L"KERNEL32");
7262 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7263 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007264 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265}
7266
Victor Stinner31b3b922013-06-05 01:49:17 +02007267/* Remove the last portion of the path */
7268static void
7269_dirnameW(WCHAR *path)
7270{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007271 WCHAR *ptr;
7272
7273 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007274 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007275 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007276 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 }
7278 *ptr = 0;
7279}
7280
Victor Stinner31b3b922013-06-05 01:49:17 +02007281/* Is this path absolute? */
7282static int
7283_is_absW(const WCHAR *path)
7284{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007285 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7286
7287}
7288
Victor Stinner31b3b922013-06-05 01:49:17 +02007289/* join root and rest with a backslash */
7290static void
7291_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7292{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007293 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007294
Victor Stinner31b3b922013-06-05 01:49:17 +02007295 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007296 wcscpy(dest_path, rest);
7297 return;
7298 }
7299
7300 root_len = wcslen(root);
7301
7302 wcscpy(dest_path, root);
7303 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007304 dest_path[root_len] = L'\\';
7305 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007306 }
7307 wcscpy(dest_path+root_len, rest);
7308}
7309
Victor Stinner31b3b922013-06-05 01:49:17 +02007310/* Return True if the path at src relative to dest is a directory */
7311static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007312_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007313{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314 WIN32_FILE_ATTRIBUTE_DATA src_info;
7315 WCHAR dest_parent[MAX_PATH];
7316 WCHAR src_resolved[MAX_PATH] = L"";
7317
7318 /* dest_parent = os.path.dirname(dest) */
7319 wcscpy(dest_parent, dest);
7320 _dirnameW(dest_parent);
7321 /* src_resolved = os.path.join(dest_parent, src) */
7322 _joinW(src_resolved, dest_parent, src);
7323 return (
7324 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7325 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7326 );
7327}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007328#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007329
Larry Hastings2f936352014-08-05 14:04:04 +10007330
7331/*[clinic input]
7332os.symlink
7333 src: path_t
7334 dst: path_t
7335 target_is_directory: bool = False
7336 *
7337 dir_fd: dir_fd(requires='symlinkat')=None
7338
7339# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7340
7341Create a symbolic link pointing to src named dst.
7342
7343target_is_directory is required on Windows if the target is to be
7344 interpreted as a directory. (On Windows, symlink requires
7345 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7346 target_is_directory is ignored on non-Windows platforms.
7347
7348If dir_fd is not None, it should be a file descriptor open to a directory,
7349 and path should be relative; path will then be relative to that directory.
7350dir_fd may not be implemented on your platform.
7351 If it is unavailable, using it will raise a NotImplementedError.
7352
7353[clinic start generated code]*/
7354
Larry Hastings2f936352014-08-05 14:04:04 +10007355static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007356os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007357 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007358/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007359{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007360#ifdef MS_WINDOWS
7361 DWORD result;
7362#else
7363 int result;
7364#endif
7365
Larry Hastings9cf065c2012-06-22 16:30:09 -07007366#ifdef MS_WINDOWS
7367 if (!check_CreateSymbolicLink()) {
7368 PyErr_SetString(PyExc_NotImplementedError,
7369 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007370 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007371 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007372 if (!win32_can_symlink) {
7373 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007374 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007375 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007376#endif
7377
Larry Hastings2f936352014-08-05 14:04:04 +10007378 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007379 PyErr_SetString(PyExc_ValueError,
7380 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007381 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007382 }
7383
7384#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007385
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007387 /* if src is a directory, ensure target_is_directory==1 */
7388 target_is_directory |= _check_dirW(src->wide, dst->wide);
7389 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7390 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007391 Py_END_ALLOW_THREADS
7392
Larry Hastings2f936352014-08-05 14:04:04 +10007393 if (!result)
7394 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395
7396#else
7397
7398 Py_BEGIN_ALLOW_THREADS
7399#if HAVE_SYMLINKAT
7400 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007401 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402 else
7403#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007404 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405 Py_END_ALLOW_THREADS
7406
Larry Hastings2f936352014-08-05 14:04:04 +10007407 if (result)
7408 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409#endif
7410
Larry Hastings2f936352014-08-05 14:04:04 +10007411 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007412}
7413#endif /* HAVE_SYMLINK */
7414
Larry Hastings9cf065c2012-06-22 16:30:09 -07007415
Brian Curtind40e6f72010-07-08 21:39:08 +00007416
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007417
Larry Hastings605a62d2012-06-24 04:33:36 -07007418static PyStructSequence_Field times_result_fields[] = {
7419 {"user", "user time"},
7420 {"system", "system time"},
7421 {"children_user", "user time of children"},
7422 {"children_system", "system time of children"},
7423 {"elapsed", "elapsed time since an arbitrary point in the past"},
7424 {NULL}
7425};
7426
7427PyDoc_STRVAR(times_result__doc__,
7428"times_result: Result from os.times().\n\n\
7429This object may be accessed either as a tuple of\n\
7430 (user, system, children_user, children_system, elapsed),\n\
7431or via the attributes user, system, children_user, children_system,\n\
7432and elapsed.\n\
7433\n\
7434See os.times for more information.");
7435
7436static PyStructSequence_Desc times_result_desc = {
7437 "times_result", /* name */
7438 times_result__doc__, /* doc */
7439 times_result_fields,
7440 5
7441};
7442
7443static PyTypeObject TimesResultType;
7444
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007445#ifdef MS_WINDOWS
7446#define HAVE_TIMES /* mandatory, for the method table */
7447#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007448
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007449#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007450
7451static PyObject *
7452build_times_result(double user, double system,
7453 double children_user, double children_system,
7454 double elapsed)
7455{
7456 PyObject *value = PyStructSequence_New(&TimesResultType);
7457 if (value == NULL)
7458 return NULL;
7459
7460#define SET(i, field) \
7461 { \
7462 PyObject *o = PyFloat_FromDouble(field); \
7463 if (!o) { \
7464 Py_DECREF(value); \
7465 return NULL; \
7466 } \
7467 PyStructSequence_SET_ITEM(value, i, o); \
7468 } \
7469
7470 SET(0, user);
7471 SET(1, system);
7472 SET(2, children_user);
7473 SET(3, children_system);
7474 SET(4, elapsed);
7475
7476#undef SET
7477
7478 return value;
7479}
7480
Larry Hastings605a62d2012-06-24 04:33:36 -07007481
Larry Hastings2f936352014-08-05 14:04:04 +10007482#ifndef MS_WINDOWS
7483#define NEED_TICKS_PER_SECOND
7484static long ticks_per_second = -1;
7485#endif /* MS_WINDOWS */
7486
7487/*[clinic input]
7488os.times
7489
7490Return a collection containing process timing information.
7491
7492The object returned behaves like a named tuple with these fields:
7493 (utime, stime, cutime, cstime, elapsed_time)
7494All fields are floating point numbers.
7495[clinic start generated code]*/
7496
Larry Hastings2f936352014-08-05 14:04:04 +10007497static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007498os_times_impl(PyObject *module)
7499/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007500#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007501{
Victor Stinner8c62be82010-05-06 00:08:46 +00007502 FILETIME create, exit, kernel, user;
7503 HANDLE hProc;
7504 hProc = GetCurrentProcess();
7505 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7506 /* The fields of a FILETIME structure are the hi and lo part
7507 of a 64-bit value expressed in 100 nanosecond units.
7508 1e7 is one second in such units; 1e-7 the inverse.
7509 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7510 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007511 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007512 (double)(user.dwHighDateTime*429.4967296 +
7513 user.dwLowDateTime*1e-7),
7514 (double)(kernel.dwHighDateTime*429.4967296 +
7515 kernel.dwLowDateTime*1e-7),
7516 (double)0,
7517 (double)0,
7518 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007519}
Larry Hastings2f936352014-08-05 14:04:04 +10007520#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007521{
Larry Hastings2f936352014-08-05 14:04:04 +10007522
7523
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007524 struct tms t;
7525 clock_t c;
7526 errno = 0;
7527 c = times(&t);
7528 if (c == (clock_t) -1)
7529 return posix_error();
7530 return build_times_result(
7531 (double)t.tms_utime / ticks_per_second,
7532 (double)t.tms_stime / ticks_per_second,
7533 (double)t.tms_cutime / ticks_per_second,
7534 (double)t.tms_cstime / ticks_per_second,
7535 (double)c / ticks_per_second);
7536}
Larry Hastings2f936352014-08-05 14:04:04 +10007537#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007538#endif /* HAVE_TIMES */
7539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007540
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007541#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007542/*[clinic input]
7543os.getsid
7544
7545 pid: pid_t
7546 /
7547
7548Call the system call getsid(pid) and return the result.
7549[clinic start generated code]*/
7550
Larry Hastings2f936352014-08-05 14:04:04 +10007551static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007552os_getsid_impl(PyObject *module, pid_t pid)
7553/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007554{
Victor Stinner8c62be82010-05-06 00:08:46 +00007555 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 sid = getsid(pid);
7557 if (sid < 0)
7558 return posix_error();
7559 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007560}
7561#endif /* HAVE_GETSID */
7562
7563
Guido van Rossumb6775db1994-08-01 11:34:53 +00007564#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007565/*[clinic input]
7566os.setsid
7567
7568Call the system call setsid().
7569[clinic start generated code]*/
7570
Larry Hastings2f936352014-08-05 14:04:04 +10007571static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007572os_setsid_impl(PyObject *module)
7573/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007574{
Victor Stinner8c62be82010-05-06 00:08:46 +00007575 if (setsid() < 0)
7576 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007577 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007578}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007579#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007580
Larry Hastings2f936352014-08-05 14:04:04 +10007581
Guido van Rossumb6775db1994-08-01 11:34:53 +00007582#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007583/*[clinic input]
7584os.setpgid
7585
7586 pid: pid_t
7587 pgrp: pid_t
7588 /
7589
7590Call the system call setpgid(pid, pgrp).
7591[clinic start generated code]*/
7592
Larry Hastings2f936352014-08-05 14:04:04 +10007593static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007594os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7595/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007596{
Victor Stinner8c62be82010-05-06 00:08:46 +00007597 if (setpgid(pid, pgrp) < 0)
7598 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007599 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007600}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007601#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007603
Guido van Rossumb6775db1994-08-01 11:34:53 +00007604#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007605/*[clinic input]
7606os.tcgetpgrp
7607
7608 fd: int
7609 /
7610
7611Return the process group associated with the terminal specified by fd.
7612[clinic start generated code]*/
7613
Larry Hastings2f936352014-08-05 14:04:04 +10007614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007615os_tcgetpgrp_impl(PyObject *module, int fd)
7616/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007617{
7618 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 if (pgid < 0)
7620 return posix_error();
7621 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007622}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007623#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Guido van Rossumb6775db1994-08-01 11:34:53 +00007626#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007627/*[clinic input]
7628os.tcsetpgrp
7629
7630 fd: int
7631 pgid: pid_t
7632 /
7633
7634Set the process group associated with the terminal specified by fd.
7635[clinic start generated code]*/
7636
Larry Hastings2f936352014-08-05 14:04:04 +10007637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007638os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7639/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007640{
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 if (tcsetpgrp(fd, pgid) < 0)
7642 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007643 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007644}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007645#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007646
Guido van Rossum687dd131993-05-17 08:34:16 +00007647/* Functions acting on file descriptors */
7648
Victor Stinnerdaf45552013-08-28 00:53:59 +02007649#ifdef O_CLOEXEC
7650extern int _Py_open_cloexec_works;
7651#endif
7652
Larry Hastings2f936352014-08-05 14:04:04 +10007653
7654/*[clinic input]
7655os.open -> int
7656 path: path_t
7657 flags: int
7658 mode: int = 0o777
7659 *
7660 dir_fd: dir_fd(requires='openat') = None
7661
7662# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7663
7664Open a file for low level IO. Returns a file descriptor (integer).
7665
7666If dir_fd is not None, it should be a file descriptor open to a directory,
7667 and path should be relative; path will then be relative to that directory.
7668dir_fd may not be implemented on your platform.
7669 If it is unavailable, using it will raise a NotImplementedError.
7670[clinic start generated code]*/
7671
Larry Hastings2f936352014-08-05 14:04:04 +10007672static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007673os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7674/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007675{
7676 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007677 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007678
Victor Stinnerdaf45552013-08-28 00:53:59 +02007679#ifdef O_CLOEXEC
7680 int *atomic_flag_works = &_Py_open_cloexec_works;
7681#elif !defined(MS_WINDOWS)
7682 int *atomic_flag_works = NULL;
7683#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007684
Victor Stinnerdaf45552013-08-28 00:53:59 +02007685#ifdef MS_WINDOWS
7686 flags |= O_NOINHERIT;
7687#elif defined(O_CLOEXEC)
7688 flags |= O_CLOEXEC;
7689#endif
7690
Steve Dower8fc89802015-04-12 00:26:27 -04007691 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007692 do {
7693 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007694#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007695 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007696#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007697#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007698 if (dir_fd != DEFAULT_DIR_FD)
7699 fd = openat(dir_fd, path->narrow, flags, mode);
7700 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007701#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007703#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007704 Py_END_ALLOW_THREADS
7705 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007706 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007707
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007708 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007709 if (!async_err)
7710 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007711 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007712 }
7713
Victor Stinnerdaf45552013-08-28 00:53:59 +02007714#ifndef MS_WINDOWS
7715 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7716 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007717 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007718 }
7719#endif
7720
Larry Hastings2f936352014-08-05 14:04:04 +10007721 return fd;
7722}
7723
7724
7725/*[clinic input]
7726os.close
7727
7728 fd: int
7729
7730Close a file descriptor.
7731[clinic start generated code]*/
7732
Barry Warsaw53699e91996-12-10 23:23:01 +00007733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007734os_close_impl(PyObject *module, int fd)
7735/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007736{
Larry Hastings2f936352014-08-05 14:04:04 +10007737 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007738 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7739 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7740 * for more details.
7741 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007743 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007745 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 Py_END_ALLOW_THREADS
7747 if (res < 0)
7748 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007749 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007750}
7751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007752
Larry Hastings2f936352014-08-05 14:04:04 +10007753/*[clinic input]
7754os.closerange
7755
7756 fd_low: int
7757 fd_high: int
7758 /
7759
7760Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7761[clinic start generated code]*/
7762
Larry Hastings2f936352014-08-05 14:04:04 +10007763static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007764os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7765/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007766{
7767 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007769 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007770 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007771 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007772 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 Py_END_ALLOW_THREADS
7774 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007775}
7776
7777
Larry Hastings2f936352014-08-05 14:04:04 +10007778/*[clinic input]
7779os.dup -> int
7780
7781 fd: int
7782 /
7783
7784Return a duplicate of a file descriptor.
7785[clinic start generated code]*/
7786
Larry Hastings2f936352014-08-05 14:04:04 +10007787static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007788os_dup_impl(PyObject *module, int fd)
7789/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007790{
7791 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007792}
7793
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007794
Larry Hastings2f936352014-08-05 14:04:04 +10007795/*[clinic input]
7796os.dup2
7797 fd: int
7798 fd2: int
7799 inheritable: bool=True
7800
7801Duplicate file descriptor.
7802[clinic start generated code]*/
7803
Larry Hastings2f936352014-08-05 14:04:04 +10007804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007805os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7806/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007807{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007808 int res;
7809#if defined(HAVE_DUP3) && \
7810 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7811 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7812 int dup3_works = -1;
7813#endif
7814
Steve Dower940f33a2016-09-08 11:21:54 -07007815 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007817
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007818 /* dup2() can fail with EINTR if the target FD is already open, because it
7819 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7820 * upon close(), and therefore below.
7821 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007822#ifdef MS_WINDOWS
7823 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007824 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007826 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007827 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 if (res < 0)
7829 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007830
7831 /* Character files like console cannot be make non-inheritable */
7832 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7833 close(fd2);
7834 return NULL;
7835 }
7836
7837#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7838 Py_BEGIN_ALLOW_THREADS
7839 if (!inheritable)
7840 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7841 else
7842 res = dup2(fd, fd2);
7843 Py_END_ALLOW_THREADS
7844 if (res < 0)
7845 return posix_error();
7846
7847#else
7848
7849#ifdef HAVE_DUP3
7850 if (!inheritable && dup3_works != 0) {
7851 Py_BEGIN_ALLOW_THREADS
7852 res = dup3(fd, fd2, O_CLOEXEC);
7853 Py_END_ALLOW_THREADS
7854 if (res < 0) {
7855 if (dup3_works == -1)
7856 dup3_works = (errno != ENOSYS);
7857 if (dup3_works)
7858 return posix_error();
7859 }
7860 }
7861
7862 if (inheritable || dup3_works == 0)
7863 {
7864#endif
7865 Py_BEGIN_ALLOW_THREADS
7866 res = dup2(fd, fd2);
7867 Py_END_ALLOW_THREADS
7868 if (res < 0)
7869 return posix_error();
7870
7871 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7872 close(fd2);
7873 return NULL;
7874 }
7875#ifdef HAVE_DUP3
7876 }
7877#endif
7878
7879#endif
7880
Larry Hastings2f936352014-08-05 14:04:04 +10007881 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007882}
7883
Larry Hastings2f936352014-08-05 14:04:04 +10007884
Ross Lagerwall7807c352011-03-17 20:20:30 +02007885#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007886/*[clinic input]
7887os.lockf
7888
7889 fd: int
7890 An open file descriptor.
7891 command: int
7892 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7893 length: Py_off_t
7894 The number of bytes to lock, starting at the current position.
7895 /
7896
7897Apply, test or remove a POSIX lock on an open file descriptor.
7898
7899[clinic start generated code]*/
7900
Larry Hastings2f936352014-08-05 14:04:04 +10007901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007902os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7903/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007904{
7905 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007906
7907 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007908 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007909 Py_END_ALLOW_THREADS
7910
7911 if (res < 0)
7912 return posix_error();
7913
7914 Py_RETURN_NONE;
7915}
Larry Hastings2f936352014-08-05 14:04:04 +10007916#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007918
Larry Hastings2f936352014-08-05 14:04:04 +10007919/*[clinic input]
7920os.lseek -> Py_off_t
7921
7922 fd: int
7923 position: Py_off_t
7924 how: int
7925 /
7926
7927Set the position of a file descriptor. Return the new position.
7928
7929Return the new cursor position in number of bytes
7930relative to the beginning of the file.
7931[clinic start generated code]*/
7932
Larry Hastings2f936352014-08-05 14:04:04 +10007933static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007934os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7935/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007936{
7937 Py_off_t result;
7938
Guido van Rossum687dd131993-05-17 08:34:16 +00007939#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7941 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007942 case 0: how = SEEK_SET; break;
7943 case 1: how = SEEK_CUR; break;
7944 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007946#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007947
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007949 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007950
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007952 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007953#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007954 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007955#else
Larry Hastings2f936352014-08-05 14:04:04 +10007956 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007957#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007958 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007959 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007960 if (result < 0)
7961 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007962
Larry Hastings2f936352014-08-05 14:04:04 +10007963 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007964}
7965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007966
Larry Hastings2f936352014-08-05 14:04:04 +10007967/*[clinic input]
7968os.read
7969 fd: int
7970 length: Py_ssize_t
7971 /
7972
7973Read from a file descriptor. Returns a bytes object.
7974[clinic start generated code]*/
7975
Larry Hastings2f936352014-08-05 14:04:04 +10007976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007977os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7978/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007979{
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 Py_ssize_t n;
7981 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007982
7983 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 errno = EINVAL;
7985 return posix_error();
7986 }
Larry Hastings2f936352014-08-05 14:04:04 +10007987
7988#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007989 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007990 if (length > INT_MAX)
7991 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007992#endif
7993
7994 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 if (buffer == NULL)
7996 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007997
Victor Stinner66aab0c2015-03-19 22:53:20 +01007998 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7999 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008001 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 }
Larry Hastings2f936352014-08-05 14:04:04 +10008003
8004 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008006
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008008}
8009
Ross Lagerwall7807c352011-03-17 20:20:30 +02008010#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8011 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008012static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008013iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008014{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008015 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008016 Py_ssize_t blen, total = 0;
8017
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008018 *iov = PyMem_New(struct iovec, cnt);
8019 if (*iov == NULL) {
8020 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008021 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008022 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008023
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008024 *buf = PyMem_New(Py_buffer, cnt);
8025 if (*buf == NULL) {
8026 PyMem_Del(*iov);
8027 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008028 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008029 }
8030
8031 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008032 PyObject *item = PySequence_GetItem(seq, i);
8033 if (item == NULL)
8034 goto fail;
8035 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8036 Py_DECREF(item);
8037 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008039 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008040 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008041 blen = (*buf)[i].len;
8042 (*iov)[i].iov_len = blen;
8043 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008044 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008045 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008046
8047fail:
8048 PyMem_Del(*iov);
8049 for (j = 0; j < i; j++) {
8050 PyBuffer_Release(&(*buf)[j]);
8051 }
8052 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008053 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054}
8055
8056static void
8057iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8058{
8059 int i;
8060 PyMem_Del(iov);
8061 for (i = 0; i < cnt; i++) {
8062 PyBuffer_Release(&buf[i]);
8063 }
8064 PyMem_Del(buf);
8065}
8066#endif
8067
Larry Hastings2f936352014-08-05 14:04:04 +10008068
Ross Lagerwall7807c352011-03-17 20:20:30 +02008069#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008070/*[clinic input]
8071os.readv -> Py_ssize_t
8072
8073 fd: int
8074 buffers: object
8075 /
8076
8077Read from a file descriptor fd into an iterable of buffers.
8078
8079The buffers should be mutable buffers accepting bytes.
8080readv will transfer data into each buffer until it is full
8081and then move on to the next buffer in the sequence to hold
8082the rest of the data.
8083
8084readv returns the total number of bytes read,
8085which may be less than the total capacity of all the buffers.
8086[clinic start generated code]*/
8087
Larry Hastings2f936352014-08-05 14:04:04 +10008088static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008089os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8090/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008091{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008092 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008093 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008094 struct iovec *iov;
8095 Py_buffer *buf;
8096
Larry Hastings2f936352014-08-05 14:04:04 +10008097 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008098 PyErr_SetString(PyExc_TypeError,
8099 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008100 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008101 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008102
Larry Hastings2f936352014-08-05 14:04:04 +10008103 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008104 if (cnt < 0)
8105 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008106
8107 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8108 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008109
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008110 do {
8111 Py_BEGIN_ALLOW_THREADS
8112 n = readv(fd, iov, cnt);
8113 Py_END_ALLOW_THREADS
8114 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008115
8116 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008117 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008118 if (!async_err)
8119 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008120 return -1;
8121 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008122
Larry Hastings2f936352014-08-05 14:04:04 +10008123 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008124}
Larry Hastings2f936352014-08-05 14:04:04 +10008125#endif /* HAVE_READV */
8126
Ross Lagerwall7807c352011-03-17 20:20:30 +02008127
8128#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008129/*[clinic input]
8130# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8131os.pread
8132
8133 fd: int
8134 length: int
8135 offset: Py_off_t
8136 /
8137
8138Read a number of bytes from a file descriptor starting at a particular offset.
8139
8140Read length bytes from file descriptor fd, starting at offset bytes from
8141the beginning of the file. The file offset remains unchanged.
8142[clinic start generated code]*/
8143
Larry Hastings2f936352014-08-05 14:04:04 +10008144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008145os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8146/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008147{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151
Larry Hastings2f936352014-08-05 14:04:04 +10008152 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008153 errno = EINVAL;
8154 return posix_error();
8155 }
Larry Hastings2f936352014-08-05 14:04:04 +10008156 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008157 if (buffer == NULL)
8158 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008159
8160 do {
8161 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008162 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008163 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008164 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008165 Py_END_ALLOW_THREADS
8166 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8167
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168 if (n < 0) {
8169 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008170 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171 }
Larry Hastings2f936352014-08-05 14:04:04 +10008172 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008173 _PyBytes_Resize(&buffer, n);
8174 return buffer;
8175}
Larry Hastings2f936352014-08-05 14:04:04 +10008176#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008177
Larry Hastings2f936352014-08-05 14:04:04 +10008178
8179/*[clinic input]
8180os.write -> Py_ssize_t
8181
8182 fd: int
8183 data: Py_buffer
8184 /
8185
8186Write a bytes object to a file descriptor.
8187[clinic start generated code]*/
8188
Larry Hastings2f936352014-08-05 14:04:04 +10008189static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008190os_write_impl(PyObject *module, int fd, Py_buffer *data)
8191/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008192{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008193 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194}
8195
8196#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008197PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008198"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008199sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008200 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008201Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008202
Larry Hastings2f936352014-08-05 14:04:04 +10008203/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008204static PyObject *
8205posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8206{
8207 int in, out;
8208 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008209 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008210 off_t offset;
8211
8212#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8213#ifndef __APPLE__
8214 Py_ssize_t len;
8215#endif
8216 PyObject *headers = NULL, *trailers = NULL;
8217 Py_buffer *hbuf, *tbuf;
8218 off_t sbytes;
8219 struct sf_hdtr sf;
8220 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008221 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008222 static char *keywords[] = {"out", "in",
8223 "offset", "count",
8224 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008225
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008226 sf.headers = NULL;
8227 sf.trailers = NULL;
8228
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008229#ifdef __APPLE__
8230 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008231 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008232#else
8233 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008234 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008235#endif
8236 &headers, &trailers, &flags))
8237 return NULL;
8238 if (headers != NULL) {
8239 if (!PySequence_Check(headers)) {
8240 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008241 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008242 return NULL;
8243 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008244 Py_ssize_t i = PySequence_Size(headers);
8245 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008246 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008247 if (i > INT_MAX) {
8248 PyErr_SetString(PyExc_OverflowError,
8249 "sendfile() header is too large");
8250 return NULL;
8251 }
8252 if (i > 0) {
8253 sf.hdr_cnt = (int)i;
8254 i = iov_setup(&(sf.headers), &hbuf,
8255 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8256 if (i < 0)
8257 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008258#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008259 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008260#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008261 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008262 }
8263 }
8264 if (trailers != NULL) {
8265 if (!PySequence_Check(trailers)) {
8266 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008267 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008268 return NULL;
8269 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008270 Py_ssize_t i = PySequence_Size(trailers);
8271 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008273 if (i > INT_MAX) {
8274 PyErr_SetString(PyExc_OverflowError,
8275 "sendfile() trailer is too large");
8276 return NULL;
8277 }
8278 if (i > 0) {
8279 sf.trl_cnt = (int)i;
8280 i = iov_setup(&(sf.trailers), &tbuf,
8281 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8282 if (i < 0)
8283 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008284#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008285 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008286#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008287 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008288 }
8289 }
8290
Steve Dower8fc89802015-04-12 00:26:27 -04008291 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008292 do {
8293 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008294#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008295 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008296#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008297 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008298#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008299 Py_END_ALLOW_THREADS
8300 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008301 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008302
8303 if (sf.headers != NULL)
8304 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8305 if (sf.trailers != NULL)
8306 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8307
8308 if (ret < 0) {
8309 if ((errno == EAGAIN) || (errno == EBUSY)) {
8310 if (sbytes != 0) {
8311 // some data has been sent
8312 goto done;
8313 }
8314 else {
8315 // no data has been sent; upper application is supposed
8316 // to retry on EAGAIN or EBUSY
8317 return posix_error();
8318 }
8319 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008320 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321 }
8322 goto done;
8323
8324done:
8325 #if !defined(HAVE_LARGEFILE_SUPPORT)
8326 return Py_BuildValue("l", sbytes);
8327 #else
8328 return Py_BuildValue("L", sbytes);
8329 #endif
8330
8331#else
8332 Py_ssize_t count;
8333 PyObject *offobj;
8334 static char *keywords[] = {"out", "in",
8335 "offset", "count", NULL};
8336 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8337 keywords, &out, &in, &offobj, &count))
8338 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008339#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008340 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008341 do {
8342 Py_BEGIN_ALLOW_THREADS
8343 ret = sendfile(out, in, NULL, count);
8344 Py_END_ALLOW_THREADS
8345 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008346 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008347 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008348 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008349 }
8350#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008351 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008352 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008353
8354 do {
8355 Py_BEGIN_ALLOW_THREADS
8356 ret = sendfile(out, in, &offset, count);
8357 Py_END_ALLOW_THREADS
8358 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008359 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008360 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008361 return Py_BuildValue("n", ret);
8362#endif
8363}
Larry Hastings2f936352014-08-05 14:04:04 +10008364#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008365
Larry Hastings2f936352014-08-05 14:04:04 +10008366
8367/*[clinic input]
8368os.fstat
8369
8370 fd : int
8371
8372Perform a stat system call on the given file descriptor.
8373
8374Like stat(), but for an open file descriptor.
8375Equivalent to os.stat(fd).
8376[clinic start generated code]*/
8377
Larry Hastings2f936352014-08-05 14:04:04 +10008378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008379os_fstat_impl(PyObject *module, int fd)
8380/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008381{
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 STRUCT_STAT st;
8383 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008384 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008385
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008386 do {
8387 Py_BEGIN_ALLOW_THREADS
8388 res = FSTAT(fd, &st);
8389 Py_END_ALLOW_THREADS
8390 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008391 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008392#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008393 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008394#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008395 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008396#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 }
Tim Peters5aa91602002-01-30 05:46:57 +00008398
Victor Stinner4195b5c2012-02-08 23:03:19 +01008399 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008400}
8401
Larry Hastings2f936352014-08-05 14:04:04 +10008402
8403/*[clinic input]
8404os.isatty -> bool
8405 fd: int
8406 /
8407
8408Return True if the fd is connected to a terminal.
8409
8410Return True if the file descriptor is an open file descriptor
8411connected to the slave end of a terminal.
8412[clinic start generated code]*/
8413
Larry Hastings2f936352014-08-05 14:04:04 +10008414static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008415os_isatty_impl(PyObject *module, int fd)
8416/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008417{
Steve Dower8fc89802015-04-12 00:26:27 -04008418 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008419 _Py_BEGIN_SUPPRESS_IPH
8420 return_value = isatty(fd);
8421 _Py_END_SUPPRESS_IPH
8422 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008423}
8424
8425
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008426#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008427/*[clinic input]
8428os.pipe
8429
8430Create a pipe.
8431
8432Returns a tuple of two file descriptors:
8433 (read_fd, write_fd)
8434[clinic start generated code]*/
8435
Larry Hastings2f936352014-08-05 14:04:04 +10008436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008437os_pipe_impl(PyObject *module)
8438/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008439{
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008441#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008443 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008444 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008445#else
8446 int res;
8447#endif
8448
8449#ifdef MS_WINDOWS
8450 attr.nLength = sizeof(attr);
8451 attr.lpSecurityDescriptor = NULL;
8452 attr.bInheritHandle = FALSE;
8453
8454 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008455 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008456 ok = CreatePipe(&read, &write, &attr, 0);
8457 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008458 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8459 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008460 if (fds[0] == -1 || fds[1] == -1) {
8461 CloseHandle(read);
8462 CloseHandle(write);
8463 ok = 0;
8464 }
8465 }
Steve Dowerc3630612016-11-19 18:41:16 -08008466 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008467 Py_END_ALLOW_THREADS
8468
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008470 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008471#else
8472
8473#ifdef HAVE_PIPE2
8474 Py_BEGIN_ALLOW_THREADS
8475 res = pipe2(fds, O_CLOEXEC);
8476 Py_END_ALLOW_THREADS
8477
8478 if (res != 0 && errno == ENOSYS)
8479 {
8480#endif
8481 Py_BEGIN_ALLOW_THREADS
8482 res = pipe(fds);
8483 Py_END_ALLOW_THREADS
8484
8485 if (res == 0) {
8486 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8487 close(fds[0]);
8488 close(fds[1]);
8489 return NULL;
8490 }
8491 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8492 close(fds[0]);
8493 close(fds[1]);
8494 return NULL;
8495 }
8496 }
8497#ifdef HAVE_PIPE2
8498 }
8499#endif
8500
8501 if (res != 0)
8502 return PyErr_SetFromErrno(PyExc_OSError);
8503#endif /* !MS_WINDOWS */
8504 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008505}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008506#endif /* HAVE_PIPE */
8507
Larry Hastings2f936352014-08-05 14:04:04 +10008508
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008509#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008510/*[clinic input]
8511os.pipe2
8512
8513 flags: int
8514 /
8515
8516Create a pipe with flags set atomically.
8517
8518Returns a tuple of two file descriptors:
8519 (read_fd, write_fd)
8520
8521flags can be constructed by ORing together one or more of these values:
8522O_NONBLOCK, O_CLOEXEC.
8523[clinic start generated code]*/
8524
Larry Hastings2f936352014-08-05 14:04:04 +10008525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008526os_pipe2_impl(PyObject *module, int flags)
8527/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008528{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008529 int fds[2];
8530 int res;
8531
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008532 res = pipe2(fds, flags);
8533 if (res != 0)
8534 return posix_error();
8535 return Py_BuildValue("(ii)", fds[0], fds[1]);
8536}
8537#endif /* HAVE_PIPE2 */
8538
Larry Hastings2f936352014-08-05 14:04:04 +10008539
Ross Lagerwall7807c352011-03-17 20:20:30 +02008540#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008541/*[clinic input]
8542os.writev -> Py_ssize_t
8543 fd: int
8544 buffers: object
8545 /
8546
8547Iterate over buffers, and write the contents of each to a file descriptor.
8548
8549Returns the total number of bytes written.
8550buffers must be a sequence of bytes-like objects.
8551[clinic start generated code]*/
8552
Larry Hastings2f936352014-08-05 14:04:04 +10008553static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008554os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8555/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008556{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008557 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008558 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008559 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008560 struct iovec *iov;
8561 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008562
8563 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008564 PyErr_SetString(PyExc_TypeError,
8565 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008566 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008567 }
Larry Hastings2f936352014-08-05 14:04:04 +10008568 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008569 if (cnt < 0)
8570 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008571
Larry Hastings2f936352014-08-05 14:04:04 +10008572 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8573 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008574 }
8575
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008576 do {
8577 Py_BEGIN_ALLOW_THREADS
8578 result = writev(fd, iov, cnt);
8579 Py_END_ALLOW_THREADS
8580 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008581
8582 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008583 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008584 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008585
Georg Brandl306336b2012-06-24 12:55:33 +02008586 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008587}
Larry Hastings2f936352014-08-05 14:04:04 +10008588#endif /* HAVE_WRITEV */
8589
8590
8591#ifdef HAVE_PWRITE
8592/*[clinic input]
8593os.pwrite -> Py_ssize_t
8594
8595 fd: int
8596 buffer: Py_buffer
8597 offset: Py_off_t
8598 /
8599
8600Write bytes to a file descriptor starting at a particular offset.
8601
8602Write buffer to fd, starting at offset bytes from the beginning of
8603the file. Returns the number of bytes writte. Does not change the
8604current file offset.
8605[clinic start generated code]*/
8606
Larry Hastings2f936352014-08-05 14:04:04 +10008607static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008608os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8609/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008610{
8611 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008612 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008613
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008614 do {
8615 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008616 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008617 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008618 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008619 Py_END_ALLOW_THREADS
8620 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008621
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008622 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008623 posix_error();
8624 return size;
8625}
8626#endif /* HAVE_PWRITE */
8627
8628
8629#ifdef HAVE_MKFIFO
8630/*[clinic input]
8631os.mkfifo
8632
8633 path: path_t
8634 mode: int=0o666
8635 *
8636 dir_fd: dir_fd(requires='mkfifoat')=None
8637
8638Create a "fifo" (a POSIX named pipe).
8639
8640If dir_fd is not None, it should be a file descriptor open to a directory,
8641 and path should be relative; path will then be relative to that directory.
8642dir_fd may not be implemented on your platform.
8643 If it is unavailable, using it will raise a NotImplementedError.
8644[clinic start generated code]*/
8645
Larry Hastings2f936352014-08-05 14:04:04 +10008646static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008647os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8648/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008649{
8650 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008651 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008652
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008653 do {
8654 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008655#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008656 if (dir_fd != DEFAULT_DIR_FD)
8657 result = mkfifoat(dir_fd, path->narrow, mode);
8658 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008659#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008660 result = mkfifo(path->narrow, mode);
8661 Py_END_ALLOW_THREADS
8662 } while (result != 0 && errno == EINTR &&
8663 !(async_err = PyErr_CheckSignals()));
8664 if (result != 0)
8665 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008666
8667 Py_RETURN_NONE;
8668}
8669#endif /* HAVE_MKFIFO */
8670
8671
8672#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8673/*[clinic input]
8674os.mknod
8675
8676 path: path_t
8677 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008678 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008679 *
8680 dir_fd: dir_fd(requires='mknodat')=None
8681
8682Create a node in the file system.
8683
8684Create a node in the file system (file, device special file or named pipe)
8685at path. mode specifies both the permissions to use and the
8686type of node to be created, being combined (bitwise OR) with one of
8687S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8688device defines the newly created device special file (probably using
8689os.makedev()). Otherwise device is ignored.
8690
8691If dir_fd is not None, it should be a file descriptor open to a directory,
8692 and path should be relative; path will then be relative to that directory.
8693dir_fd may not be implemented on your platform.
8694 If it is unavailable, using it will raise a NotImplementedError.
8695[clinic start generated code]*/
8696
Larry Hastings2f936352014-08-05 14:04:04 +10008697static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008698os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008699 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008700/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008701{
8702 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008703 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008704
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008705 do {
8706 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008707#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008708 if (dir_fd != DEFAULT_DIR_FD)
8709 result = mknodat(dir_fd, path->narrow, mode, device);
8710 else
Larry Hastings2f936352014-08-05 14:04:04 +10008711#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008712 result = mknod(path->narrow, mode, device);
8713 Py_END_ALLOW_THREADS
8714 } while (result != 0 && errno == EINTR &&
8715 !(async_err = PyErr_CheckSignals()));
8716 if (result != 0)
8717 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008718
8719 Py_RETURN_NONE;
8720}
8721#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8722
8723
8724#ifdef HAVE_DEVICE_MACROS
8725/*[clinic input]
8726os.major -> 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 major 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_major_impl(PyObject *module, dev_t device)
8736/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008737{
8738 return major(device);
8739}
8740
8741
8742/*[clinic input]
8743os.minor -> unsigned_int
8744
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008745 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008746 /
8747
8748Extracts a device minor number from a raw device number.
8749[clinic start generated code]*/
8750
Larry Hastings2f936352014-08-05 14:04:04 +10008751static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008752os_minor_impl(PyObject *module, dev_t device)
8753/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008754{
8755 return minor(device);
8756}
8757
8758
8759/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008760os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008761
8762 major: int
8763 minor: int
8764 /
8765
8766Composes a raw device number from the major and minor device numbers.
8767[clinic start generated code]*/
8768
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008769static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008770os_makedev_impl(PyObject *module, int major, int minor)
8771/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008772{
8773 return makedev(major, minor);
8774}
8775#endif /* HAVE_DEVICE_MACROS */
8776
8777
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008778#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008779/*[clinic input]
8780os.ftruncate
8781
8782 fd: int
8783 length: Py_off_t
8784 /
8785
8786Truncate a file, specified by file descriptor, to a specific length.
8787[clinic start generated code]*/
8788
Larry Hastings2f936352014-08-05 14:04:04 +10008789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008790os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8791/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008792{
8793 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008794 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008795
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008796 do {
8797 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008798 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008799#ifdef MS_WINDOWS
8800 result = _chsize_s(fd, length);
8801#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008802 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008803#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008804 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008805 Py_END_ALLOW_THREADS
8806 } while (result != 0 && errno == EINTR &&
8807 !(async_err = PyErr_CheckSignals()));
8808 if (result != 0)
8809 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008810 Py_RETURN_NONE;
8811}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008812#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008813
8814
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008815#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008816/*[clinic input]
8817os.truncate
8818 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8819 length: Py_off_t
8820
8821Truncate a file, specified by path, to a specific length.
8822
8823On some platforms, path may also be specified as an open file descriptor.
8824 If this functionality is unavailable, using it raises an exception.
8825[clinic start generated code]*/
8826
Larry Hastings2f936352014-08-05 14:04:04 +10008827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008828os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8829/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008830{
8831 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008832#ifdef MS_WINDOWS
8833 int fd;
8834#endif
8835
8836 if (path->fd != -1)
8837 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008838
8839 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008840 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008841#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008842 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008843 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008844 result = -1;
8845 else {
8846 result = _chsize_s(fd, length);
8847 close(fd);
8848 if (result < 0)
8849 errno = result;
8850 }
8851#else
8852 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008853#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008854 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008855 Py_END_ALLOW_THREADS
8856 if (result < 0)
8857 return path_error(path);
8858
8859 Py_RETURN_NONE;
8860}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008861#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008862
Ross Lagerwall7807c352011-03-17 20:20:30 +02008863
Victor Stinnerd6b17692014-09-30 12:20:05 +02008864/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8865 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8866 defined, which is the case in Python on AIX. AIX bug report:
8867 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8868#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8869# define POSIX_FADVISE_AIX_BUG
8870#endif
8871
Victor Stinnerec39e262014-09-30 12:35:58 +02008872
Victor Stinnerd6b17692014-09-30 12:20:05 +02008873#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008874/*[clinic input]
8875os.posix_fallocate
8876
8877 fd: int
8878 offset: Py_off_t
8879 length: Py_off_t
8880 /
8881
8882Ensure a file has allocated at least a particular number of bytes on disk.
8883
8884Ensure that the file specified by fd encompasses a range of bytes
8885starting at offset bytes from the beginning and continuing for length bytes.
8886[clinic start generated code]*/
8887
Larry Hastings2f936352014-08-05 14:04:04 +10008888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008889os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008890 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008891/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008892{
8893 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008894 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008895
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008896 do {
8897 Py_BEGIN_ALLOW_THREADS
8898 result = posix_fallocate(fd, offset, length);
8899 Py_END_ALLOW_THREADS
8900 } while (result != 0 && errno == EINTR &&
8901 !(async_err = PyErr_CheckSignals()));
8902 if (result != 0)
8903 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008904 Py_RETURN_NONE;
8905}
Victor Stinnerec39e262014-09-30 12:35:58 +02008906#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008907
Ross Lagerwall7807c352011-03-17 20:20:30 +02008908
Victor Stinnerd6b17692014-09-30 12:20:05 +02008909#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008910/*[clinic input]
8911os.posix_fadvise
8912
8913 fd: int
8914 offset: Py_off_t
8915 length: Py_off_t
8916 advice: int
8917 /
8918
8919Announce an intention to access data in a specific pattern.
8920
8921Announce an intention to access data in a specific pattern, thus allowing
8922the kernel to make optimizations.
8923The advice applies to the region of the file specified by fd starting at
8924offset and continuing for length bytes.
8925advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8926POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8927POSIX_FADV_DONTNEED.
8928[clinic start generated code]*/
8929
Larry Hastings2f936352014-08-05 14:04:04 +10008930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008931os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008932 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008933/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008934{
8935 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008936 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008937
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008938 do {
8939 Py_BEGIN_ALLOW_THREADS
8940 result = posix_fadvise(fd, offset, length, advice);
8941 Py_END_ALLOW_THREADS
8942 } while (result != 0 && errno == EINTR &&
8943 !(async_err = PyErr_CheckSignals()));
8944 if (result != 0)
8945 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008946 Py_RETURN_NONE;
8947}
Victor Stinnerec39e262014-09-30 12:35:58 +02008948#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008949
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008950#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008951
Fred Drake762e2061999-08-26 17:23:54 +00008952/* Save putenv() parameters as values here, so we can collect them when they
8953 * get re-set with another call for the same key. */
8954static PyObject *posix_putenv_garbage;
8955
Larry Hastings2f936352014-08-05 14:04:04 +10008956static void
8957posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008958{
Larry Hastings2f936352014-08-05 14:04:04 +10008959 /* Install the first arg and newstr in posix_putenv_garbage;
8960 * this will cause previous value to be collected. This has to
8961 * happen after the real putenv() call because the old value
8962 * was still accessible until then. */
8963 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8964 /* really not much we can do; just leak */
8965 PyErr_Clear();
8966 else
8967 Py_DECREF(value);
8968}
8969
8970
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008971#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008972/*[clinic input]
8973os.putenv
8974
8975 name: unicode
8976 value: unicode
8977 /
8978
8979Change or add an environment variable.
8980[clinic start generated code]*/
8981
Larry Hastings2f936352014-08-05 14:04:04 +10008982static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008983os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8984/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008985{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008986 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008987
8988 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8989 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008990 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008991 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008992 }
Larry Hastings2f936352014-08-05 14:04:04 +10008993 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008994 PyErr_Format(PyExc_ValueError,
8995 "the environment variable is longer than %u characters",
8996 _MAX_ENV);
8997 goto error;
8998 }
8999
Larry Hastings2f936352014-08-05 14:04:04 +10009000 env = PyUnicode_AsUnicode(unicode);
9001 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009002 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009003 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009005 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009007
Larry Hastings2f936352014-08-05 14:04:04 +10009008 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009009 Py_RETURN_NONE;
9010
9011error:
Larry Hastings2f936352014-08-05 14:04:04 +10009012 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009013 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009014}
Larry Hastings2f936352014-08-05 14:04:04 +10009015#else /* MS_WINDOWS */
9016/*[clinic input]
9017os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009018
Larry Hastings2f936352014-08-05 14:04:04 +10009019 name: FSConverter
9020 value: FSConverter
9021 /
9022
9023Change or add an environment variable.
9024[clinic start generated code]*/
9025
Larry Hastings2f936352014-08-05 14:04:04 +10009026static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009027os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9028/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009029{
9030 PyObject *bytes = NULL;
9031 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009032 const char *name_string = PyBytes_AsString(name);
9033 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009034
9035 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9036 if (bytes == NULL) {
9037 PyErr_NoMemory();
9038 return NULL;
9039 }
9040
9041 env = PyBytes_AS_STRING(bytes);
9042 if (putenv(env)) {
9043 Py_DECREF(bytes);
9044 return posix_error();
9045 }
9046
9047 posix_putenv_garbage_setitem(name, bytes);
9048 Py_RETURN_NONE;
9049}
9050#endif /* MS_WINDOWS */
9051#endif /* HAVE_PUTENV */
9052
9053
9054#ifdef HAVE_UNSETENV
9055/*[clinic input]
9056os.unsetenv
9057 name: FSConverter
9058 /
9059
9060Delete an environment variable.
9061[clinic start generated code]*/
9062
Larry Hastings2f936352014-08-05 14:04:04 +10009063static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009064os_unsetenv_impl(PyObject *module, PyObject *name)
9065/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009066{
Victor Stinner984890f2011-11-24 13:53:38 +01009067#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009068 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009069#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009070
Victor Stinner984890f2011-11-24 13:53:38 +01009071#ifdef HAVE_BROKEN_UNSETENV
9072 unsetenv(PyBytes_AS_STRING(name));
9073#else
Victor Stinner65170952011-11-22 22:16:17 +01009074 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009075 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009076 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009077#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009078
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 /* Remove the key from posix_putenv_garbage;
9080 * this will cause it to be collected. This has to
9081 * happen after the real unsetenv() call because the
9082 * old value was still accessible until then.
9083 */
Victor Stinner65170952011-11-22 22:16:17 +01009084 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 /* really not much we can do; just leak */
9086 PyErr_Clear();
9087 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009088 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009089}
Larry Hastings2f936352014-08-05 14:04:04 +10009090#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009091
Larry Hastings2f936352014-08-05 14:04:04 +10009092
9093/*[clinic input]
9094os.strerror
9095
9096 code: int
9097 /
9098
9099Translate an error code to a message string.
9100[clinic start generated code]*/
9101
Larry Hastings2f936352014-08-05 14:04:04 +10009102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009103os_strerror_impl(PyObject *module, int code)
9104/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009105{
9106 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 if (message == NULL) {
9108 PyErr_SetString(PyExc_ValueError,
9109 "strerror() argument out of range");
9110 return NULL;
9111 }
Victor Stinner1b579672011-12-17 05:47:23 +01009112 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009113}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009114
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009115
Guido van Rossumc9641791998-08-04 15:26:23 +00009116#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009117#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009118/*[clinic input]
9119os.WCOREDUMP -> bool
9120
9121 status: int
9122 /
9123
9124Return True if the process returning status was dumped to a core file.
9125[clinic start generated code]*/
9126
Larry Hastings2f936352014-08-05 14:04:04 +10009127static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009128os_WCOREDUMP_impl(PyObject *module, int status)
9129/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009130{
9131 WAIT_TYPE wait_status;
9132 WAIT_STATUS_INT(wait_status) = status;
9133 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009134}
9135#endif /* WCOREDUMP */
9136
Larry Hastings2f936352014-08-05 14:04:04 +10009137
Fred Drake106c1a02002-04-23 15:58:02 +00009138#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009139/*[clinic input]
9140os.WIFCONTINUED -> bool
9141
9142 status: int
9143
9144Return True if a particular process was continued from a job control stop.
9145
9146Return True if the process returning status was continued from a
9147job control stop.
9148[clinic start generated code]*/
9149
Larry Hastings2f936352014-08-05 14:04:04 +10009150static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009151os_WIFCONTINUED_impl(PyObject *module, int status)
9152/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009153{
9154 WAIT_TYPE wait_status;
9155 WAIT_STATUS_INT(wait_status) = status;
9156 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009157}
9158#endif /* WIFCONTINUED */
9159
Larry Hastings2f936352014-08-05 14:04:04 +10009160
Guido van Rossumc9641791998-08-04 15:26:23 +00009161#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009162/*[clinic input]
9163os.WIFSTOPPED -> bool
9164
9165 status: int
9166
9167Return True if the process returning status was stopped.
9168[clinic start generated code]*/
9169
Larry Hastings2f936352014-08-05 14:04:04 +10009170static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009171os_WIFSTOPPED_impl(PyObject *module, int status)
9172/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009173{
9174 WAIT_TYPE wait_status;
9175 WAIT_STATUS_INT(wait_status) = status;
9176 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009177}
9178#endif /* WIFSTOPPED */
9179
Larry Hastings2f936352014-08-05 14:04:04 +10009180
Guido van Rossumc9641791998-08-04 15:26:23 +00009181#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009182/*[clinic input]
9183os.WIFSIGNALED -> bool
9184
9185 status: int
9186
9187Return True if the process returning status was terminated by a signal.
9188[clinic start generated code]*/
9189
Larry Hastings2f936352014-08-05 14:04:04 +10009190static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009191os_WIFSIGNALED_impl(PyObject *module, int status)
9192/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009193{
9194 WAIT_TYPE wait_status;
9195 WAIT_STATUS_INT(wait_status) = status;
9196 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009197}
9198#endif /* WIFSIGNALED */
9199
Larry Hastings2f936352014-08-05 14:04:04 +10009200
Guido van Rossumc9641791998-08-04 15:26:23 +00009201#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009202/*[clinic input]
9203os.WIFEXITED -> bool
9204
9205 status: int
9206
9207Return True if the process returning status exited via the exit() system call.
9208[clinic start generated code]*/
9209
Larry Hastings2f936352014-08-05 14:04:04 +10009210static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009211os_WIFEXITED_impl(PyObject *module, int status)
9212/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009213{
9214 WAIT_TYPE wait_status;
9215 WAIT_STATUS_INT(wait_status) = status;
9216 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009217}
9218#endif /* WIFEXITED */
9219
Larry Hastings2f936352014-08-05 14:04:04 +10009220
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009221#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009222/*[clinic input]
9223os.WEXITSTATUS -> int
9224
9225 status: int
9226
9227Return the process return code from status.
9228[clinic start generated code]*/
9229
Larry Hastings2f936352014-08-05 14:04:04 +10009230static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009231os_WEXITSTATUS_impl(PyObject *module, int status)
9232/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009233{
9234 WAIT_TYPE wait_status;
9235 WAIT_STATUS_INT(wait_status) = status;
9236 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009237}
9238#endif /* WEXITSTATUS */
9239
Larry Hastings2f936352014-08-05 14:04:04 +10009240
Guido van Rossumc9641791998-08-04 15:26:23 +00009241#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009242/*[clinic input]
9243os.WTERMSIG -> int
9244
9245 status: int
9246
9247Return the signal that terminated the process that provided the status value.
9248[clinic start generated code]*/
9249
Larry Hastings2f936352014-08-05 14:04:04 +10009250static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009251os_WTERMSIG_impl(PyObject *module, int status)
9252/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009253{
9254 WAIT_TYPE wait_status;
9255 WAIT_STATUS_INT(wait_status) = status;
9256 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009257}
9258#endif /* WTERMSIG */
9259
Larry Hastings2f936352014-08-05 14:04:04 +10009260
Guido van Rossumc9641791998-08-04 15:26:23 +00009261#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009262/*[clinic input]
9263os.WSTOPSIG -> int
9264
9265 status: int
9266
9267Return the signal that stopped the process that provided the status value.
9268[clinic start generated code]*/
9269
Larry Hastings2f936352014-08-05 14:04:04 +10009270static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009271os_WSTOPSIG_impl(PyObject *module, int status)
9272/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009273{
9274 WAIT_TYPE wait_status;
9275 WAIT_STATUS_INT(wait_status) = status;
9276 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009277}
9278#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009279#endif /* HAVE_SYS_WAIT_H */
9280
9281
Thomas Wouters477c8d52006-05-27 19:21:47 +00009282#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009283#ifdef _SCO_DS
9284/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9285 needed definitions in sys/statvfs.h */
9286#define _SVID3
9287#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009288#include <sys/statvfs.h>
9289
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009290static PyObject*
9291_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009292 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9293 if (v == NULL)
9294 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009295
9296#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9298 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9299 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9300 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9301 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9302 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9303 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9304 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9305 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#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9309 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9310 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009311 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009313 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009315 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009317 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009319 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009321 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9323 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009324#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009325 if (PyErr_Occurred()) {
9326 Py_DECREF(v);
9327 return NULL;
9328 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009329
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009331}
9332
Larry Hastings2f936352014-08-05 14:04:04 +10009333
9334/*[clinic input]
9335os.fstatvfs
9336 fd: int
9337 /
9338
9339Perform an fstatvfs system call on the given fd.
9340
9341Equivalent to statvfs(fd).
9342[clinic start generated code]*/
9343
Larry Hastings2f936352014-08-05 14:04:04 +10009344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009345os_fstatvfs_impl(PyObject *module, int fd)
9346/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009347{
9348 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009349 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009351
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009352 do {
9353 Py_BEGIN_ALLOW_THREADS
9354 result = fstatvfs(fd, &st);
9355 Py_END_ALLOW_THREADS
9356 } while (result != 0 && errno == EINTR &&
9357 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009358 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009359 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009360
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009362}
Larry Hastings2f936352014-08-05 14:04:04 +10009363#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009364
9365
Thomas Wouters477c8d52006-05-27 19:21:47 +00009366#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009367#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009368/*[clinic input]
9369os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009370
Larry Hastings2f936352014-08-05 14:04:04 +10009371 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9372
9373Perform a statvfs system call on the given path.
9374
9375path may always be specified as a string.
9376On some platforms, path may also be specified as an open file descriptor.
9377 If this functionality is unavailable, using it raises an exception.
9378[clinic start generated code]*/
9379
Larry Hastings2f936352014-08-05 14:04:04 +10009380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009381os_statvfs_impl(PyObject *module, path_t *path)
9382/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009383{
9384 int result;
9385 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009386
9387 Py_BEGIN_ALLOW_THREADS
9388#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009389 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009390#ifdef __APPLE__
9391 /* handle weak-linking on Mac OS X 10.3 */
9392 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009393 fd_specified("statvfs", path->fd);
9394 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009395 }
9396#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009397 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009398 }
9399 else
9400#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009401 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009402 Py_END_ALLOW_THREADS
9403
9404 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009405 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009406 }
9407
Larry Hastings2f936352014-08-05 14:04:04 +10009408 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009409}
Larry Hastings2f936352014-08-05 14:04:04 +10009410#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9411
Guido van Rossum94f6f721999-01-06 18:42:14 +00009412
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009413#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009414/*[clinic input]
9415os._getdiskusage
9416
9417 path: Py_UNICODE
9418
9419Return disk usage statistics about the given path as a (total, free) tuple.
9420[clinic start generated code]*/
9421
Larry Hastings2f936352014-08-05 14:04:04 +10009422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009423os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9424/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009425{
9426 BOOL retval;
9427 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009428
9429 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009430 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009431 Py_END_ALLOW_THREADS
9432 if (retval == 0)
9433 return PyErr_SetFromWindowsErr(0);
9434
9435 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9436}
Larry Hastings2f936352014-08-05 14:04:04 +10009437#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009438
9439
Fred Drakec9680921999-12-13 16:37:25 +00009440/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9441 * It maps strings representing configuration variable names to
9442 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009443 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009444 * rarely-used constants. There are three separate tables that use
9445 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009446 *
9447 * This code is always included, even if none of the interfaces that
9448 * need it are included. The #if hackery needed to avoid it would be
9449 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009450 */
9451struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009452 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009453 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009454};
9455
Fred Drake12c6e2d1999-12-14 21:25:03 +00009456static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009457conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009458 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009459{
Christian Heimes217cfd12007-12-02 14:31:20 +00009460 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009461 int value = _PyLong_AsInt(arg);
9462 if (value == -1 && PyErr_Occurred())
9463 return 0;
9464 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009465 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009466 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009467 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009468 /* look up the value in the table using a binary search */
9469 size_t lo = 0;
9470 size_t mid;
9471 size_t hi = tablesize;
9472 int cmp;
9473 const char *confname;
9474 if (!PyUnicode_Check(arg)) {
9475 PyErr_SetString(PyExc_TypeError,
9476 "configuration names must be strings or integers");
9477 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009479 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009480 if (confname == NULL)
9481 return 0;
9482 while (lo < hi) {
9483 mid = (lo + hi) / 2;
9484 cmp = strcmp(confname, table[mid].name);
9485 if (cmp < 0)
9486 hi = mid;
9487 else if (cmp > 0)
9488 lo = mid + 1;
9489 else {
9490 *valuep = table[mid].value;
9491 return 1;
9492 }
9493 }
9494 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9495 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009497}
9498
9499
9500#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9501static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009502#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009504#endif
9505#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009507#endif
Fred Drakec9680921999-12-13 16:37:25 +00009508#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
9511#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009513#endif
9514#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
9517#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009519#endif
9520#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009522#endif
9523#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
9526#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009528#endif
9529#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009531#endif
9532#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009534#endif
9535#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009537#endif
9538#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009540#endif
9541#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009553#ifdef _PC_ACL_ENABLED
9554 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9555#endif
9556#ifdef _PC_MIN_HOLE_SIZE
9557 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9558#endif
9559#ifdef _PC_ALLOC_SIZE_MIN
9560 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9561#endif
9562#ifdef _PC_REC_INCR_XFER_SIZE
9563 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9564#endif
9565#ifdef _PC_REC_MAX_XFER_SIZE
9566 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9567#endif
9568#ifdef _PC_REC_MIN_XFER_SIZE
9569 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9570#endif
9571#ifdef _PC_REC_XFER_ALIGN
9572 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9573#endif
9574#ifdef _PC_SYMLINK_MAX
9575 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9576#endif
9577#ifdef _PC_XATTR_ENABLED
9578 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9579#endif
9580#ifdef _PC_XATTR_EXISTS
9581 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9582#endif
9583#ifdef _PC_TIMESTAMP_RESOLUTION
9584 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9585#endif
Fred Drakec9680921999-12-13 16:37:25 +00009586};
9587
Fred Drakec9680921999-12-13 16:37:25 +00009588static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009589conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009590{
9591 return conv_confname(arg, valuep, posix_constants_pathconf,
9592 sizeof(posix_constants_pathconf)
9593 / sizeof(struct constdef));
9594}
9595#endif
9596
Larry Hastings2f936352014-08-05 14:04:04 +10009597
Fred Drakec9680921999-12-13 16:37:25 +00009598#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009599/*[clinic input]
9600os.fpathconf -> long
9601
9602 fd: int
9603 name: path_confname
9604 /
9605
9606Return the configuration limit name for the file descriptor fd.
9607
9608If there is no limit, return -1.
9609[clinic start generated code]*/
9610
Larry Hastings2f936352014-08-05 14:04:04 +10009611static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009612os_fpathconf_impl(PyObject *module, int fd, int name)
9613/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009614{
9615 long limit;
9616
9617 errno = 0;
9618 limit = fpathconf(fd, name);
9619 if (limit == -1 && errno != 0)
9620 posix_error();
9621
9622 return limit;
9623}
9624#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009625
9626
9627#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009628/*[clinic input]
9629os.pathconf -> long
9630 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9631 name: path_confname
9632
9633Return the configuration limit name for the file or directory path.
9634
9635If there is no limit, return -1.
9636On some platforms, path may also be specified as an open file descriptor.
9637 If this functionality is unavailable, using it raises an exception.
9638[clinic start generated code]*/
9639
Larry Hastings2f936352014-08-05 14:04:04 +10009640static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009641os_pathconf_impl(PyObject *module, path_t *path, int name)
9642/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009643{
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009645
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009647#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009648 if (path->fd != -1)
9649 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009650 else
9651#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009652 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 if (limit == -1 && errno != 0) {
9654 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009655 /* could be a path or name problem */
9656 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009657 else
Larry Hastings2f936352014-08-05 14:04:04 +10009658 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 }
Larry Hastings2f936352014-08-05 14:04:04 +10009660
9661 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009662}
Larry Hastings2f936352014-08-05 14:04:04 +10009663#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009664
9665#ifdef HAVE_CONFSTR
9666static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009667#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009669#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009670#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009672#endif
9673#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009675#endif
Fred Draked86ed291999-12-15 15:34:33 +00009676#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009678#endif
9679#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009681#endif
9682#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009684#endif
9685#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009687#endif
Fred Drakec9680921999-12-13 16:37:25 +00009688#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009690#endif
9691#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009693#endif
9694#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
9700#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009702#endif
9703#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009705#endif
9706#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
9709#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009711#endif
Fred Draked86ed291999-12-15 15:34:33 +00009712#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009714#endif
Fred Drakec9680921999-12-13 16:37:25 +00009715#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009717#endif
Fred Draked86ed291999-12-15 15:34:33 +00009718#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009720#endif
9721#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009723#endif
9724#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009726#endif
9727#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009729#endif
Fred Drakec9680921999-12-13 16:37:25 +00009730#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
Fred Draked86ed291999-12-15 15:34:33 +00009778#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009780#endif
9781#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009783#endif
9784#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009786#endif
9787#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009789#endif
9790#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009792#endif
9793#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009795#endif
9796#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009798#endif
9799#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009801#endif
9802#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009804#endif
9805#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009807#endif
9808#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009810#endif
9811#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009813#endif
9814#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009816#endif
Fred Drakec9680921999-12-13 16:37:25 +00009817};
9818
9819static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009820conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009821{
9822 return conv_confname(arg, valuep, posix_constants_confstr,
9823 sizeof(posix_constants_confstr)
9824 / sizeof(struct constdef));
9825}
9826
Larry Hastings2f936352014-08-05 14:04:04 +10009827
9828/*[clinic input]
9829os.confstr
9830
9831 name: confstr_confname
9832 /
9833
9834Return a string-valued system configuration variable.
9835[clinic start generated code]*/
9836
Larry Hastings2f936352014-08-05 14:04:04 +10009837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009838os_confstr_impl(PyObject *module, int name)
9839/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009840{
9841 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009842 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009843 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009844
Victor Stinnercb043522010-09-10 23:49:04 +00009845 errno = 0;
9846 len = confstr(name, buffer, sizeof(buffer));
9847 if (len == 0) {
9848 if (errno) {
9849 posix_error();
9850 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009851 }
9852 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009853 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009854 }
9855 }
Victor Stinnercb043522010-09-10 23:49:04 +00009856
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009857 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009858 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009859 char *buf = PyMem_Malloc(len);
9860 if (buf == NULL)
9861 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009862 len2 = confstr(name, buf, len);
9863 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009864 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009865 PyMem_Free(buf);
9866 }
9867 else
9868 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009869 return result;
9870}
Larry Hastings2f936352014-08-05 14:04:04 +10009871#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009872
9873
9874#ifdef HAVE_SYSCONF
9875static struct constdef posix_constants_sysconf[] = {
9876#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
Fred Draked86ed291999-12-15 15:34:33 +00009906#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009908#endif
9909#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009911#endif
Fred Drakec9680921999-12-13 16:37:25 +00009912#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
Fred Drakec9680921999-12-13 16:37:25 +00009915#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
Fred Draked86ed291999-12-15 15:34:33 +00009930#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009932#endif
Fred Drakec9680921999-12-13 16:37:25 +00009933#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
Fred Draked86ed291999-12-15 15:34:33 +00009948#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009950#endif
Fred Drakec9680921999-12-13 16:37:25 +00009951#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
Fred Draked86ed291999-12-15 15:34:33 +000010020#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010022#endif
Fred Drakec9680921999-12-13 16:37:25 +000010023#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
Fred Draked86ed291999-12-15 15:34:33 +000010032#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
Fred Drakec9680921999-12-13 16:37:25 +000010035#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
Fred Draked86ed291999-12-15 15:34:33 +000010038#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010040#endif
10041#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010043#endif
Fred Drakec9680921999-12-13 16:37:25 +000010044#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
Fred Draked86ed291999-12-15 15:34:33 +000010056#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010058#endif
Fred Drakec9680921999-12-13 16:37:25 +000010059#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
Fred Draked86ed291999-12-15 15:34:33 +000010080#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010082#endif
Fred Drakec9680921999-12-13 16:37:25 +000010083#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
Fred Draked86ed291999-12-15 15:34:33 +000010089#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010091#endif
Fred Drakec9680921999-12-13 16:37:25 +000010092#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
Fred Draked86ed291999-12-15 15:34:33 +000010119#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010121#endif
10122#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010124#endif
Fred Drakec9680921999-12-13 16:37:25 +000010125#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
Fred Draked86ed291999-12-15 15:34:33 +000010230#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010232#endif
Fred Drakec9680921999-12-13 16:37:25 +000010233#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
10263#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010283#endif
10284#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
10350#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010352#endif
10353#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
10359#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368};
10369
10370static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010371conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010372{
10373 return conv_confname(arg, valuep, posix_constants_sysconf,
10374 sizeof(posix_constants_sysconf)
10375 / sizeof(struct constdef));
10376}
10377
Larry Hastings2f936352014-08-05 14:04:04 +100010378
10379/*[clinic input]
10380os.sysconf -> long
10381 name: sysconf_confname
10382 /
10383
10384Return an integer-valued system configuration variable.
10385[clinic start generated code]*/
10386
Larry Hastings2f936352014-08-05 14:04:04 +100010387static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010388os_sysconf_impl(PyObject *module, int name)
10389/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010390{
10391 long value;
10392
10393 errno = 0;
10394 value = sysconf(name);
10395 if (value == -1 && errno != 0)
10396 posix_error();
10397 return value;
10398}
10399#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010400
10401
Fred Drakebec628d1999-12-15 18:31:10 +000010402/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010403 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010404 * the exported dictionaries that are used to publish information about the
10405 * names available on the host platform.
10406 *
10407 * Sorting the table at runtime ensures that the table is properly ordered
10408 * when used, even for platforms we're not able to test on. It also makes
10409 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010410 */
Fred Drakebec628d1999-12-15 18:31:10 +000010411
10412static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010413cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010414{
10415 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010417 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010419
10420 return strcmp(c1->name, c2->name);
10421}
10422
10423static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010424setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010425 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010426{
Fred Drakebec628d1999-12-15 18:31:10 +000010427 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010428 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010429
10430 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10431 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010432 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010434
Barry Warsaw3155db32000-04-13 15:20:40 +000010435 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 PyObject *o = PyLong_FromLong(table[i].value);
10437 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10438 Py_XDECREF(o);
10439 Py_DECREF(d);
10440 return -1;
10441 }
10442 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010443 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010444 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010445}
10446
Fred Drakebec628d1999-12-15 18:31:10 +000010447/* Return -1 on failure, 0 on success. */
10448static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010449setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010450{
10451#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010452 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010453 sizeof(posix_constants_pathconf)
10454 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010455 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010456 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010457#endif
10458#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010459 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010460 sizeof(posix_constants_confstr)
10461 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010462 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010463 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010464#endif
10465#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010466 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010467 sizeof(posix_constants_sysconf)
10468 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010469 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010470 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010471#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010472 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010473}
Fred Draked86ed291999-12-15 15:34:33 +000010474
10475
Larry Hastings2f936352014-08-05 14:04:04 +100010476/*[clinic input]
10477os.abort
10478
10479Abort the interpreter immediately.
10480
10481This function 'dumps core' or otherwise fails in the hardest way possible
10482on the hosting operating system. This function never returns.
10483[clinic start generated code]*/
10484
Larry Hastings2f936352014-08-05 14:04:04 +100010485static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010486os_abort_impl(PyObject *module)
10487/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010488{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010489 abort();
10490 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010491#ifndef __clang__
10492 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10493 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10494 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010495 Py_FatalError("abort() called from Python code didn't abort!");
10496 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010497#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010498}
Fred Drakebec628d1999-12-15 18:31:10 +000010499
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010500#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010501/* Grab ShellExecute dynamically from shell32 */
10502static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010503static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10504 LPCWSTR, INT);
10505static int
10506check_ShellExecute()
10507{
10508 HINSTANCE hShell32;
10509
10510 /* only recheck */
10511 if (-1 == has_ShellExecute) {
10512 Py_BEGIN_ALLOW_THREADS
10513 hShell32 = LoadLibraryW(L"SHELL32");
10514 Py_END_ALLOW_THREADS
10515 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010516 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10517 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010518 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010519 } else {
10520 has_ShellExecute = 0;
10521 }
10522 }
10523 return has_ShellExecute;
10524}
10525
10526
Steve Dowercc16be82016-09-08 10:35:16 -070010527/*[clinic input]
10528os.startfile
10529 filepath: path_t
10530 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010531
Steve Dowercc16be82016-09-08 10:35:16 -070010532startfile(filepath [, operation])
10533
10534Start a file with its associated application.
10535
10536When "operation" is not specified or "open", this acts like
10537double-clicking the file in Explorer, or giving the file name as an
10538argument to the DOS "start" command: the file is opened with whatever
10539application (if any) its extension is associated.
10540When another "operation" is given, it specifies what should be done with
10541the file. A typical operation is "print".
10542
10543startfile returns as soon as the associated application is launched.
10544There is no option to wait for the application to close, and no way
10545to retrieve the application's exit status.
10546
10547The filepath is relative to the current directory. If you want to use
10548an absolute path, make sure the first character is not a slash ("/");
10549the underlying Win32 ShellExecute function doesn't work if it is.
10550[clinic start generated code]*/
10551
10552static PyObject *
10553os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10554/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10555{
10556 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010557
10558 if(!check_ShellExecute()) {
10559 /* If the OS doesn't have ShellExecute, return a
10560 NotImplementedError. */
10561 return PyErr_Format(PyExc_NotImplementedError,
10562 "startfile not available on this platform");
10563 }
10564
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010566 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010567 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 Py_END_ALLOW_THREADS
10569
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010571 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010572 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 }
Steve Dowercc16be82016-09-08 10:35:16 -070010574 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010575}
Larry Hastings2f936352014-08-05 14:04:04 +100010576#endif /* MS_WINDOWS */
10577
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010578
Martin v. Löwis438b5342002-12-27 10:16:42 +000010579#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010580/*[clinic input]
10581os.getloadavg
10582
10583Return average recent system load information.
10584
10585Return the number of processes in the system run queue averaged over
10586the last 1, 5, and 15 minutes as a tuple of three floats.
10587Raises OSError if the load average was unobtainable.
10588[clinic start generated code]*/
10589
Larry Hastings2f936352014-08-05 14:04:04 +100010590static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010591os_getloadavg_impl(PyObject *module)
10592/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010593{
10594 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010595 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010596 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10597 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010598 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010599 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010600}
Larry Hastings2f936352014-08-05 14:04:04 +100010601#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010602
Larry Hastings2f936352014-08-05 14:04:04 +100010603
10604/*[clinic input]
10605os.device_encoding
10606 fd: int
10607
10608Return a string describing the encoding of a terminal's file descriptor.
10609
10610The file descriptor must be attached to a terminal.
10611If the device is not a terminal, return None.
10612[clinic start generated code]*/
10613
Larry Hastings2f936352014-08-05 14:04:04 +100010614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010615os_device_encoding_impl(PyObject *module, int fd)
10616/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010617{
Brett Cannonefb00c02012-02-29 18:31:31 -050010618 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010619}
10620
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010621
Larry Hastings2f936352014-08-05 14:04:04 +100010622#ifdef HAVE_SETRESUID
10623/*[clinic input]
10624os.setresuid
10625
10626 ruid: uid_t
10627 euid: uid_t
10628 suid: uid_t
10629 /
10630
10631Set the current process's real, effective, and saved user ids.
10632[clinic start generated code]*/
10633
Larry Hastings2f936352014-08-05 14:04:04 +100010634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010635os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10636/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010637{
Victor Stinner8c62be82010-05-06 00:08:46 +000010638 if (setresuid(ruid, euid, suid) < 0)
10639 return posix_error();
10640 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010641}
Larry Hastings2f936352014-08-05 14:04:04 +100010642#endif /* HAVE_SETRESUID */
10643
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010644
10645#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010646/*[clinic input]
10647os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010648
Larry Hastings2f936352014-08-05 14:04:04 +100010649 rgid: gid_t
10650 egid: gid_t
10651 sgid: gid_t
10652 /
10653
10654Set the current process's real, effective, and saved group ids.
10655[clinic start generated code]*/
10656
Larry Hastings2f936352014-08-05 14:04:04 +100010657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010658os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10659/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010660{
Victor Stinner8c62be82010-05-06 00:08:46 +000010661 if (setresgid(rgid, egid, sgid) < 0)
10662 return posix_error();
10663 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010664}
Larry Hastings2f936352014-08-05 14:04:04 +100010665#endif /* HAVE_SETRESGID */
10666
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010667
10668#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010669/*[clinic input]
10670os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010671
Larry Hastings2f936352014-08-05 14:04:04 +100010672Return a tuple of the current process's real, effective, and saved user ids.
10673[clinic start generated code]*/
10674
Larry Hastings2f936352014-08-05 14:04:04 +100010675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010676os_getresuid_impl(PyObject *module)
10677/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010678{
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010680 if (getresuid(&ruid, &euid, &suid) < 0)
10681 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010682 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10683 _PyLong_FromUid(euid),
10684 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010685}
Larry Hastings2f936352014-08-05 14:04:04 +100010686#endif /* HAVE_GETRESUID */
10687
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010688
10689#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010690/*[clinic input]
10691os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010692
Larry Hastings2f936352014-08-05 14:04:04 +100010693Return a tuple of the current process's real, effective, and saved group ids.
10694[clinic start generated code]*/
10695
Larry Hastings2f936352014-08-05 14:04:04 +100010696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010697os_getresgid_impl(PyObject *module)
10698/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010699{
10700 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010701 if (getresgid(&rgid, &egid, &sgid) < 0)
10702 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010703 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10704 _PyLong_FromGid(egid),
10705 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010706}
Larry Hastings2f936352014-08-05 14:04:04 +100010707#endif /* HAVE_GETRESGID */
10708
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010709
Benjamin Peterson9428d532011-09-14 11:45:52 -040010710#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010711/*[clinic input]
10712os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010713
Larry Hastings2f936352014-08-05 14:04:04 +100010714 path: path_t(allow_fd=True)
10715 attribute: path_t
10716 *
10717 follow_symlinks: bool = True
10718
10719Return the value of extended attribute attribute on path.
10720
10721path may be either a string or an open file descriptor.
10722If follow_symlinks is False, and the last element of the path is a symbolic
10723 link, getxattr will examine the symbolic link itself instead of the file
10724 the link points to.
10725
10726[clinic start generated code]*/
10727
Larry Hastings2f936352014-08-05 14:04:04 +100010728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010729os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010730 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010731/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010732{
10733 Py_ssize_t i;
10734 PyObject *buffer = NULL;
10735
10736 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10737 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010738
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 for (i = 0; ; i++) {
10740 void *ptr;
10741 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010742 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 Py_ssize_t buffer_size = buffer_sizes[i];
10744 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010745 path_error(path);
10746 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747 }
10748 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10749 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010750 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010752
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010754 if (path->fd >= 0)
10755 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010756 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010757 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758 else
Larry Hastings2f936352014-08-05 14:04:04 +100010759 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010760 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010761
Larry Hastings9cf065c2012-06-22 16:30:09 -070010762 if (result < 0) {
10763 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010764 if (errno == ERANGE)
10765 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010766 path_error(path);
10767 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010769
Larry Hastings9cf065c2012-06-22 16:30:09 -070010770 if (result != buffer_size) {
10771 /* Can only shrink. */
10772 _PyBytes_Resize(&buffer, result);
10773 }
10774 break;
10775 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010776
Larry Hastings9cf065c2012-06-22 16:30:09 -070010777 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010778}
10779
Larry Hastings2f936352014-08-05 14:04:04 +100010780
10781/*[clinic input]
10782os.setxattr
10783
10784 path: path_t(allow_fd=True)
10785 attribute: path_t
10786 value: Py_buffer
10787 flags: int = 0
10788 *
10789 follow_symlinks: bool = True
10790
10791Set extended attribute attribute on path to value.
10792
10793path may be either a string or an open file descriptor.
10794If follow_symlinks is False, and the last element of the path is a symbolic
10795 link, setxattr will modify the symbolic link itself instead of the file
10796 the link points to.
10797
10798[clinic start generated code]*/
10799
Benjamin Peterson799bd802011-08-31 22:15:17 -040010800static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010801os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010802 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010803/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010804{
Larry Hastings2f936352014-08-05 14:04:04 +100010805 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010806
Larry Hastings2f936352014-08-05 14:04:04 +100010807 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010808 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010809
Benjamin Peterson799bd802011-08-31 22:15:17 -040010810 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010811 if (path->fd > -1)
10812 result = fsetxattr(path->fd, attribute->narrow,
10813 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010815 result = setxattr(path->narrow, attribute->narrow,
10816 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 else
Larry Hastings2f936352014-08-05 14:04:04 +100010818 result = lsetxattr(path->narrow, attribute->narrow,
10819 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010821
Larry Hastings9cf065c2012-06-22 16:30:09 -070010822 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010823 path_error(path);
10824 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010825 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010826
Larry Hastings2f936352014-08-05 14:04:04 +100010827 Py_RETURN_NONE;
10828}
10829
10830
10831/*[clinic input]
10832os.removexattr
10833
10834 path: path_t(allow_fd=True)
10835 attribute: path_t
10836 *
10837 follow_symlinks: bool = True
10838
10839Remove extended attribute attribute on path.
10840
10841path may be either a string or an open file descriptor.
10842If follow_symlinks is False, and the last element of the path is a symbolic
10843 link, removexattr will modify the symbolic link itself instead of the file
10844 the link points to.
10845
10846[clinic start generated code]*/
10847
Larry Hastings2f936352014-08-05 14:04:04 +100010848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010849os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010850 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010851/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010852{
10853 ssize_t result;
10854
10855 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10856 return NULL;
10857
10858 Py_BEGIN_ALLOW_THREADS;
10859 if (path->fd > -1)
10860 result = fremovexattr(path->fd, attribute->narrow);
10861 else if (follow_symlinks)
10862 result = removexattr(path->narrow, attribute->narrow);
10863 else
10864 result = lremovexattr(path->narrow, attribute->narrow);
10865 Py_END_ALLOW_THREADS;
10866
10867 if (result) {
10868 return path_error(path);
10869 }
10870
10871 Py_RETURN_NONE;
10872}
10873
10874
10875/*[clinic input]
10876os.listxattr
10877
10878 path: path_t(allow_fd=True, nullable=True) = None
10879 *
10880 follow_symlinks: bool = True
10881
10882Return a list of extended attributes on path.
10883
10884path may be either None, a string, or an open file descriptor.
10885if path is None, listxattr will examine the current directory.
10886If follow_symlinks is False, and the last element of the path is a symbolic
10887 link, listxattr will examine the symbolic link itself instead of the file
10888 the link points to.
10889[clinic start generated code]*/
10890
Larry Hastings2f936352014-08-05 14:04:04 +100010891static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010892os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10893/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010894{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010895 Py_ssize_t i;
10896 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010897 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010898 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010899
Larry Hastings2f936352014-08-05 14:04:04 +100010900 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010901 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010902
Larry Hastings2f936352014-08-05 14:04:04 +100010903 name = path->narrow ? path->narrow : ".";
10904
Larry Hastings9cf065c2012-06-22 16:30:09 -070010905 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010906 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010907 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010908 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010909 Py_ssize_t buffer_size = buffer_sizes[i];
10910 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010911 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010912 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010913 break;
10914 }
10915 buffer = PyMem_MALLOC(buffer_size);
10916 if (!buffer) {
10917 PyErr_NoMemory();
10918 break;
10919 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010920
Larry Hastings9cf065c2012-06-22 16:30:09 -070010921 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010922 if (path->fd > -1)
10923 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010924 else if (follow_symlinks)
10925 length = listxattr(name, buffer, buffer_size);
10926 else
10927 length = llistxattr(name, buffer, buffer_size);
10928 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010929
Larry Hastings9cf065c2012-06-22 16:30:09 -070010930 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010931 if (errno == ERANGE) {
10932 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010933 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010934 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010935 }
Larry Hastings2f936352014-08-05 14:04:04 +100010936 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010937 break;
10938 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010939
Larry Hastings9cf065c2012-06-22 16:30:09 -070010940 result = PyList_New(0);
10941 if (!result) {
10942 goto exit;
10943 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010944
Larry Hastings9cf065c2012-06-22 16:30:09 -070010945 end = buffer + length;
10946 for (trace = start = buffer; trace != end; trace++) {
10947 if (!*trace) {
10948 int error;
10949 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10950 trace - start);
10951 if (!attribute) {
10952 Py_DECREF(result);
10953 result = NULL;
10954 goto exit;
10955 }
10956 error = PyList_Append(result, attribute);
10957 Py_DECREF(attribute);
10958 if (error) {
10959 Py_DECREF(result);
10960 result = NULL;
10961 goto exit;
10962 }
10963 start = trace + 1;
10964 }
10965 }
10966 break;
10967 }
10968exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010969 if (buffer)
10970 PyMem_FREE(buffer);
10971 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010972}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010973#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010974
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010975
Larry Hastings2f936352014-08-05 14:04:04 +100010976/*[clinic input]
10977os.urandom
10978
10979 size: Py_ssize_t
10980 /
10981
10982Return a bytes object containing random bytes suitable for cryptographic use.
10983[clinic start generated code]*/
10984
Larry Hastings2f936352014-08-05 14:04:04 +100010985static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010986os_urandom_impl(PyObject *module, Py_ssize_t size)
10987/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010988{
10989 PyObject *bytes;
10990 int result;
10991
Georg Brandl2fb477c2012-02-21 00:33:36 +010010992 if (size < 0)
10993 return PyErr_Format(PyExc_ValueError,
10994 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010995 bytes = PyBytes_FromStringAndSize(NULL, size);
10996 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010997 return NULL;
10998
Victor Stinnere66987e2016-09-06 16:33:52 -070010999 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011000 if (result == -1) {
11001 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011002 return NULL;
11003 }
Larry Hastings2f936352014-08-05 14:04:04 +100011004 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011005}
11006
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011007/* Terminal size querying */
11008
11009static PyTypeObject TerminalSizeType;
11010
11011PyDoc_STRVAR(TerminalSize_docstring,
11012 "A tuple of (columns, lines) for holding terminal window size");
11013
11014static PyStructSequence_Field TerminalSize_fields[] = {
11015 {"columns", "width of the terminal window in characters"},
11016 {"lines", "height of the terminal window in characters"},
11017 {NULL, NULL}
11018};
11019
11020static PyStructSequence_Desc TerminalSize_desc = {
11021 "os.terminal_size",
11022 TerminalSize_docstring,
11023 TerminalSize_fields,
11024 2,
11025};
11026
11027#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011028/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011029PyDoc_STRVAR(termsize__doc__,
11030 "Return the size of the terminal window as (columns, lines).\n" \
11031 "\n" \
11032 "The optional argument fd (default standard output) specifies\n" \
11033 "which file descriptor should be queried.\n" \
11034 "\n" \
11035 "If the file descriptor is not connected to a terminal, an OSError\n" \
11036 "is thrown.\n" \
11037 "\n" \
11038 "This function will only be defined if an implementation is\n" \
11039 "available for this system.\n" \
11040 "\n" \
11041 "shutil.get_terminal_size is the high-level function which should \n" \
11042 "normally be used, os.get_terminal_size is the low-level implementation.");
11043
11044static PyObject*
11045get_terminal_size(PyObject *self, PyObject *args)
11046{
11047 int columns, lines;
11048 PyObject *termsize;
11049
11050 int fd = fileno(stdout);
11051 /* Under some conditions stdout may not be connected and
11052 * fileno(stdout) may point to an invalid file descriptor. For example
11053 * GUI apps don't have valid standard streams by default.
11054 *
11055 * If this happens, and the optional fd argument is not present,
11056 * the ioctl below will fail returning EBADF. This is what we want.
11057 */
11058
11059 if (!PyArg_ParseTuple(args, "|i", &fd))
11060 return NULL;
11061
11062#ifdef TERMSIZE_USE_IOCTL
11063 {
11064 struct winsize w;
11065 if (ioctl(fd, TIOCGWINSZ, &w))
11066 return PyErr_SetFromErrno(PyExc_OSError);
11067 columns = w.ws_col;
11068 lines = w.ws_row;
11069 }
11070#endif /* TERMSIZE_USE_IOCTL */
11071
11072#ifdef TERMSIZE_USE_CONIO
11073 {
11074 DWORD nhandle;
11075 HANDLE handle;
11076 CONSOLE_SCREEN_BUFFER_INFO csbi;
11077 switch (fd) {
11078 case 0: nhandle = STD_INPUT_HANDLE;
11079 break;
11080 case 1: nhandle = STD_OUTPUT_HANDLE;
11081 break;
11082 case 2: nhandle = STD_ERROR_HANDLE;
11083 break;
11084 default:
11085 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11086 }
11087 handle = GetStdHandle(nhandle);
11088 if (handle == NULL)
11089 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11090 if (handle == INVALID_HANDLE_VALUE)
11091 return PyErr_SetFromWindowsErr(0);
11092
11093 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11094 return PyErr_SetFromWindowsErr(0);
11095
11096 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11097 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11098 }
11099#endif /* TERMSIZE_USE_CONIO */
11100
11101 termsize = PyStructSequence_New(&TerminalSizeType);
11102 if (termsize == NULL)
11103 return NULL;
11104 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11105 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11106 if (PyErr_Occurred()) {
11107 Py_DECREF(termsize);
11108 return NULL;
11109 }
11110 return termsize;
11111}
11112#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11113
Larry Hastings2f936352014-08-05 14:04:04 +100011114
11115/*[clinic input]
11116os.cpu_count
11117
Charles-François Natali80d62e62015-08-13 20:37:08 +010011118Return the number of CPUs in the system; return None if indeterminable.
11119
11120This number is not equivalent to the number of CPUs the current process can
11121use. The number of usable CPUs can be obtained with
11122``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011123[clinic start generated code]*/
11124
Larry Hastings2f936352014-08-05 14:04:04 +100011125static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011126os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011127/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011128{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011129 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011130#ifdef MS_WINDOWS
11131 SYSTEM_INFO sysinfo;
11132 GetSystemInfo(&sysinfo);
11133 ncpu = sysinfo.dwNumberOfProcessors;
11134#elif defined(__hpux)
11135 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11136#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11137 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011138#elif defined(__DragonFly__) || \
11139 defined(__OpenBSD__) || \
11140 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011141 defined(__NetBSD__) || \
11142 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011143 int mib[2];
11144 size_t len = sizeof(ncpu);
11145 mib[0] = CTL_HW;
11146 mib[1] = HW_NCPU;
11147 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11148 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011149#endif
11150 if (ncpu >= 1)
11151 return PyLong_FromLong(ncpu);
11152 else
11153 Py_RETURN_NONE;
11154}
11155
Victor Stinnerdaf45552013-08-28 00:53:59 +020011156
Larry Hastings2f936352014-08-05 14:04:04 +100011157/*[clinic input]
11158os.get_inheritable -> bool
11159
11160 fd: int
11161 /
11162
11163Get the close-on-exe flag of the specified file descriptor.
11164[clinic start generated code]*/
11165
Larry Hastings2f936352014-08-05 14:04:04 +100011166static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011167os_get_inheritable_impl(PyObject *module, int fd)
11168/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011169{
Steve Dower8fc89802015-04-12 00:26:27 -040011170 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011171 _Py_BEGIN_SUPPRESS_IPH
11172 return_value = _Py_get_inheritable(fd);
11173 _Py_END_SUPPRESS_IPH
11174 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011175}
11176
11177
11178/*[clinic input]
11179os.set_inheritable
11180 fd: int
11181 inheritable: int
11182 /
11183
11184Set the inheritable flag of the specified file descriptor.
11185[clinic start generated code]*/
11186
Larry Hastings2f936352014-08-05 14:04:04 +100011187static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011188os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11189/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011190{
Steve Dower8fc89802015-04-12 00:26:27 -040011191 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011192
Steve Dower8fc89802015-04-12 00:26:27 -040011193 _Py_BEGIN_SUPPRESS_IPH
11194 result = _Py_set_inheritable(fd, inheritable, NULL);
11195 _Py_END_SUPPRESS_IPH
11196 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011197 return NULL;
11198 Py_RETURN_NONE;
11199}
11200
11201
11202#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011203/*[clinic input]
11204os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011205 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011206 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011207
Larry Hastings2f936352014-08-05 14:04:04 +100011208Get the close-on-exe flag of the specified file descriptor.
11209[clinic start generated code]*/
11210
Larry Hastings2f936352014-08-05 14:04:04 +100011211static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011212os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011213/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011214{
11215 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011216
11217 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11218 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011219 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011220 }
11221
Larry Hastings2f936352014-08-05 14:04:04 +100011222 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011223}
11224
Victor Stinnerdaf45552013-08-28 00:53:59 +020011225
Larry Hastings2f936352014-08-05 14:04:04 +100011226/*[clinic input]
11227os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011228 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011229 inheritable: bool
11230 /
11231
11232Set the inheritable flag of the specified handle.
11233[clinic start generated code]*/
11234
Larry Hastings2f936352014-08-05 14:04:04 +100011235static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011236os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011237 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011238/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011239{
11240 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011241 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11242 PyErr_SetFromWindowsErr(0);
11243 return NULL;
11244 }
11245 Py_RETURN_NONE;
11246}
Larry Hastings2f936352014-08-05 14:04:04 +100011247#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011248
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011249#ifndef MS_WINDOWS
11250PyDoc_STRVAR(get_blocking__doc__,
11251 "get_blocking(fd) -> bool\n" \
11252 "\n" \
11253 "Get the blocking mode of the file descriptor:\n" \
11254 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11255
11256static PyObject*
11257posix_get_blocking(PyObject *self, PyObject *args)
11258{
11259 int fd;
11260 int blocking;
11261
11262 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11263 return NULL;
11264
Steve Dower8fc89802015-04-12 00:26:27 -040011265 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011266 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011267 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011268 if (blocking < 0)
11269 return NULL;
11270 return PyBool_FromLong(blocking);
11271}
11272
11273PyDoc_STRVAR(set_blocking__doc__,
11274 "set_blocking(fd, blocking)\n" \
11275 "\n" \
11276 "Set the blocking mode of the specified file descriptor.\n" \
11277 "Set the O_NONBLOCK flag if blocking is False,\n" \
11278 "clear the O_NONBLOCK flag otherwise.");
11279
11280static PyObject*
11281posix_set_blocking(PyObject *self, PyObject *args)
11282{
Steve Dower8fc89802015-04-12 00:26:27 -040011283 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011284
11285 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11286 return NULL;
11287
Steve Dower8fc89802015-04-12 00:26:27 -040011288 _Py_BEGIN_SUPPRESS_IPH
11289 result = _Py_set_blocking(fd, blocking);
11290 _Py_END_SUPPRESS_IPH
11291 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011292 return NULL;
11293 Py_RETURN_NONE;
11294}
11295#endif /* !MS_WINDOWS */
11296
11297
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011298/*[clinic input]
11299class os.DirEntry "DirEntry *" "&DirEntryType"
11300[clinic start generated code]*/
11301/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011302
11303typedef struct {
11304 PyObject_HEAD
11305 PyObject *name;
11306 PyObject *path;
11307 PyObject *stat;
11308 PyObject *lstat;
11309#ifdef MS_WINDOWS
11310 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011311 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011312 int got_file_index;
11313#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011314#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011315 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011316#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011317 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011318 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011319#endif
11320} DirEntry;
11321
11322static void
11323DirEntry_dealloc(DirEntry *entry)
11324{
11325 Py_XDECREF(entry->name);
11326 Py_XDECREF(entry->path);
11327 Py_XDECREF(entry->stat);
11328 Py_XDECREF(entry->lstat);
11329 Py_TYPE(entry)->tp_free((PyObject *)entry);
11330}
11331
11332/* Forward reference */
11333static int
11334DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11335
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011336/*[clinic input]
11337os.DirEntry.is_symlink -> bool
11338
11339Return True if the entry is a symbolic link; cached per entry.
11340[clinic start generated code]*/
11341
Victor Stinner6036e442015-03-08 01:58:04 +010011342static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011343os_DirEntry_is_symlink_impl(DirEntry *self)
11344/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011345{
11346#ifdef MS_WINDOWS
11347 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011348#elif defined(HAVE_DIRENT_D_TYPE)
11349 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011350 if (self->d_type != DT_UNKNOWN)
11351 return self->d_type == DT_LNK;
11352 else
11353 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011354#else
11355 /* POSIX without d_type */
11356 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011357#endif
11358}
11359
11360static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011361DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11362{
11363 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011364 STRUCT_STAT st;
11365 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011366
11367#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011368 if (!PyUnicode_FSDecoder(self->path, &ub))
11369 return NULL;
11370 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011371#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011372 if (!PyUnicode_FSConverter(self->path, &ub))
11373 return NULL;
11374 const char *path = PyBytes_AS_STRING(ub);
11375 if (self->dir_fd != DEFAULT_DIR_FD) {
11376#ifdef HAVE_FSTATAT
11377 result = fstatat(self->dir_fd, path, &st,
11378 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11379#else
11380 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11381 return NULL;
11382#endif /* HAVE_FSTATAT */
11383 }
11384 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011385#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011386 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011387 if (follow_symlinks)
11388 result = STAT(path, &st);
11389 else
11390 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011391 }
11392 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011393
11394 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011395 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011396
11397 return _pystat_fromstructstat(&st);
11398}
11399
11400static PyObject *
11401DirEntry_get_lstat(DirEntry *self)
11402{
11403 if (!self->lstat) {
11404#ifdef MS_WINDOWS
11405 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11406#else /* POSIX */
11407 self->lstat = DirEntry_fetch_stat(self, 0);
11408#endif
11409 }
11410 Py_XINCREF(self->lstat);
11411 return self->lstat;
11412}
11413
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011414/*[clinic input]
11415os.DirEntry.stat
11416 *
11417 follow_symlinks: bool = True
11418
11419Return stat_result object for the entry; cached per entry.
11420[clinic start generated code]*/
11421
Victor Stinner6036e442015-03-08 01:58:04 +010011422static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011423os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11424/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011425{
11426 if (!follow_symlinks)
11427 return DirEntry_get_lstat(self);
11428
11429 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011430 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011431 if (result == -1)
11432 return NULL;
11433 else if (result)
11434 self->stat = DirEntry_fetch_stat(self, 1);
11435 else
11436 self->stat = DirEntry_get_lstat(self);
11437 }
11438
11439 Py_XINCREF(self->stat);
11440 return self->stat;
11441}
11442
Victor Stinner6036e442015-03-08 01:58:04 +010011443/* Set exception and return -1 on error, 0 for False, 1 for True */
11444static int
11445DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11446{
11447 PyObject *stat = NULL;
11448 PyObject *st_mode = NULL;
11449 long mode;
11450 int result;
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 int is_symlink;
11453 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011454#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011455#ifdef MS_WINDOWS
11456 unsigned long dir_bits;
11457#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011458 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011459
11460#ifdef MS_WINDOWS
11461 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11462 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011463#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011464 is_symlink = self->d_type == DT_LNK;
11465 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11466#endif
11467
Victor Stinner35a97c02015-03-08 02:59:09 +010011468#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011469 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011470#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011471 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011472 if (!stat) {
11473 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11474 /* If file doesn't exist (anymore), then return False
11475 (i.e., say it's not a file/directory) */
11476 PyErr_Clear();
11477 return 0;
11478 }
11479 goto error;
11480 }
11481 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11482 if (!st_mode)
11483 goto error;
11484
11485 mode = PyLong_AsLong(st_mode);
11486 if (mode == -1 && PyErr_Occurred())
11487 goto error;
11488 Py_CLEAR(st_mode);
11489 Py_CLEAR(stat);
11490 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011491#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011492 }
11493 else if (is_symlink) {
11494 assert(mode_bits != S_IFLNK);
11495 result = 0;
11496 }
11497 else {
11498 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11499#ifdef MS_WINDOWS
11500 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11501 if (mode_bits == S_IFDIR)
11502 result = dir_bits != 0;
11503 else
11504 result = dir_bits == 0;
11505#else /* POSIX */
11506 if (mode_bits == S_IFDIR)
11507 result = self->d_type == DT_DIR;
11508 else
11509 result = self->d_type == DT_REG;
11510#endif
11511 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011512#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011513
11514 return result;
11515
11516error:
11517 Py_XDECREF(st_mode);
11518 Py_XDECREF(stat);
11519 return -1;
11520}
11521
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011522/*[clinic input]
11523os.DirEntry.is_dir -> bool
11524 *
11525 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011526
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011527Return True if the entry is a directory; cached per entry.
11528[clinic start generated code]*/
11529
11530static int
11531os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11532/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11533{
11534 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011535}
11536
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011537/*[clinic input]
11538os.DirEntry.is_file -> bool
11539 *
11540 follow_symlinks: bool = True
11541
11542Return True if the entry is a file; cached per entry.
11543[clinic start generated code]*/
11544
11545static int
11546os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11547/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011548{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011549 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011550}
11551
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011552/*[clinic input]
11553os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011554
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011555Return inode of the entry; cached per entry.
11556[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011557
11558static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011559os_DirEntry_inode_impl(DirEntry *self)
11560/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011561{
11562#ifdef MS_WINDOWS
11563 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011564 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011565 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011566 STRUCT_STAT stat;
11567 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011568
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011569 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011570 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011571 path = PyUnicode_AsUnicode(unicode);
11572 result = LSTAT(path, &stat);
11573 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011574
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011575 if (result != 0)
11576 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011577
11578 self->win32_file_index = stat.st_ino;
11579 self->got_file_index = 1;
11580 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011581 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11582 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011583#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011584 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11585 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011586#endif
11587}
11588
11589static PyObject *
11590DirEntry_repr(DirEntry *self)
11591{
11592 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11593}
11594
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011595/*[clinic input]
11596os.DirEntry.__fspath__
11597
11598Returns the path for the entry.
11599[clinic start generated code]*/
11600
Brett Cannon96881cd2016-06-10 14:37:21 -070011601static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011602os_DirEntry___fspath___impl(DirEntry *self)
11603/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011604{
11605 Py_INCREF(self->path);
11606 return self->path;
11607}
11608
Victor Stinner6036e442015-03-08 01:58:04 +010011609static PyMemberDef DirEntry_members[] = {
11610 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11611 "the entry's base filename, relative to scandir() \"path\" argument"},
11612 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11613 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11614 {NULL}
11615};
11616
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011617#include "clinic/posixmodule.c.h"
11618
Victor Stinner6036e442015-03-08 01:58:04 +010011619static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011620 OS_DIRENTRY_IS_DIR_METHODDEF
11621 OS_DIRENTRY_IS_FILE_METHODDEF
11622 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11623 OS_DIRENTRY_STAT_METHODDEF
11624 OS_DIRENTRY_INODE_METHODDEF
11625 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011626 {NULL}
11627};
11628
Benjamin Peterson5646de42015-04-12 17:56:34 -040011629static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011630 PyVarObject_HEAD_INIT(NULL, 0)
11631 MODNAME ".DirEntry", /* tp_name */
11632 sizeof(DirEntry), /* tp_basicsize */
11633 0, /* tp_itemsize */
11634 /* methods */
11635 (destructor)DirEntry_dealloc, /* tp_dealloc */
11636 0, /* tp_print */
11637 0, /* tp_getattr */
11638 0, /* tp_setattr */
11639 0, /* tp_compare */
11640 (reprfunc)DirEntry_repr, /* tp_repr */
11641 0, /* tp_as_number */
11642 0, /* tp_as_sequence */
11643 0, /* tp_as_mapping */
11644 0, /* tp_hash */
11645 0, /* tp_call */
11646 0, /* tp_str */
11647 0, /* tp_getattro */
11648 0, /* tp_setattro */
11649 0, /* tp_as_buffer */
11650 Py_TPFLAGS_DEFAULT, /* tp_flags */
11651 0, /* tp_doc */
11652 0, /* tp_traverse */
11653 0, /* tp_clear */
11654 0, /* tp_richcompare */
11655 0, /* tp_weaklistoffset */
11656 0, /* tp_iter */
11657 0, /* tp_iternext */
11658 DirEntry_methods, /* tp_methods */
11659 DirEntry_members, /* tp_members */
11660};
11661
11662#ifdef MS_WINDOWS
11663
11664static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011665join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011666{
11667 Py_ssize_t path_len;
11668 Py_ssize_t size;
11669 wchar_t *result;
11670 wchar_t ch;
11671
11672 if (!path_wide) { /* Default arg: "." */
11673 path_wide = L".";
11674 path_len = 1;
11675 }
11676 else {
11677 path_len = wcslen(path_wide);
11678 }
11679
11680 /* The +1's are for the path separator and the NUL */
11681 size = path_len + 1 + wcslen(filename) + 1;
11682 result = PyMem_New(wchar_t, size);
11683 if (!result) {
11684 PyErr_NoMemory();
11685 return NULL;
11686 }
11687 wcscpy(result, path_wide);
11688 if (path_len > 0) {
11689 ch = result[path_len - 1];
11690 if (ch != SEP && ch != ALTSEP && ch != L':')
11691 result[path_len++] = SEP;
11692 wcscpy(result + path_len, filename);
11693 }
11694 return result;
11695}
11696
11697static PyObject *
11698DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11699{
11700 DirEntry *entry;
11701 BY_HANDLE_FILE_INFORMATION file_info;
11702 ULONG reparse_tag;
11703 wchar_t *joined_path;
11704
11705 entry = PyObject_New(DirEntry, &DirEntryType);
11706 if (!entry)
11707 return NULL;
11708 entry->name = NULL;
11709 entry->path = NULL;
11710 entry->stat = NULL;
11711 entry->lstat = NULL;
11712 entry->got_file_index = 0;
11713
11714 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11715 if (!entry->name)
11716 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011717 if (path->narrow) {
11718 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11719 if (!entry->name)
11720 goto error;
11721 }
Victor Stinner6036e442015-03-08 01:58:04 +010011722
11723 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11724 if (!joined_path)
11725 goto error;
11726
11727 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11728 PyMem_Free(joined_path);
11729 if (!entry->path)
11730 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011731 if (path->narrow) {
11732 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11733 if (!entry->path)
11734 goto error;
11735 }
Victor Stinner6036e442015-03-08 01:58:04 +010011736
Steve Dowercc16be82016-09-08 10:35:16 -070011737 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011738 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11739
11740 return (PyObject *)entry;
11741
11742error:
11743 Py_DECREF(entry);
11744 return NULL;
11745}
11746
11747#else /* POSIX */
11748
11749static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011750join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011751{
11752 Py_ssize_t path_len;
11753 Py_ssize_t size;
11754 char *result;
11755
11756 if (!path_narrow) { /* Default arg: "." */
11757 path_narrow = ".";
11758 path_len = 1;
11759 }
11760 else {
11761 path_len = strlen(path_narrow);
11762 }
11763
11764 if (filename_len == -1)
11765 filename_len = strlen(filename);
11766
11767 /* The +1's are for the path separator and the NUL */
11768 size = path_len + 1 + filename_len + 1;
11769 result = PyMem_New(char, size);
11770 if (!result) {
11771 PyErr_NoMemory();
11772 return NULL;
11773 }
11774 strcpy(result, path_narrow);
11775 if (path_len > 0 && result[path_len - 1] != '/')
11776 result[path_len++] = '/';
11777 strcpy(result + path_len, filename);
11778 return result;
11779}
11780
11781static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011782DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011783 ino_t d_ino
11784#ifdef HAVE_DIRENT_D_TYPE
11785 , unsigned char d_type
11786#endif
11787 )
Victor Stinner6036e442015-03-08 01:58:04 +010011788{
11789 DirEntry *entry;
11790 char *joined_path;
11791
11792 entry = PyObject_New(DirEntry, &DirEntryType);
11793 if (!entry)
11794 return NULL;
11795 entry->name = NULL;
11796 entry->path = NULL;
11797 entry->stat = NULL;
11798 entry->lstat = NULL;
11799
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011800 if (path->fd != -1) {
11801 entry->dir_fd = path->fd;
11802 joined_path = NULL;
11803 }
11804 else {
11805 entry->dir_fd = DEFAULT_DIR_FD;
11806 joined_path = join_path_filename(path->narrow, name, name_len);
11807 if (!joined_path)
11808 goto error;
11809 }
Victor Stinner6036e442015-03-08 01:58:04 +010011810
11811 if (!path->narrow || !PyBytes_Check(path->object)) {
11812 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011813 if (joined_path)
11814 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011815 }
11816 else {
11817 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011818 if (joined_path)
11819 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011820 }
11821 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011822 if (!entry->name)
11823 goto error;
11824
11825 if (path->fd != -1) {
11826 entry->path = entry->name;
11827 Py_INCREF(entry->path);
11828 }
11829 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011830 goto error;
11831
Victor Stinner35a97c02015-03-08 02:59:09 +010011832#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011833 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011834#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011835 entry->d_ino = d_ino;
11836
11837 return (PyObject *)entry;
11838
11839error:
11840 Py_XDECREF(entry);
11841 return NULL;
11842}
11843
11844#endif
11845
11846
11847typedef struct {
11848 PyObject_HEAD
11849 path_t path;
11850#ifdef MS_WINDOWS
11851 HANDLE handle;
11852 WIN32_FIND_DATAW file_data;
11853 int first_time;
11854#else /* POSIX */
11855 DIR *dirp;
11856#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011857#ifdef HAVE_FDOPENDIR
11858 int fd;
11859#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011860} ScandirIterator;
11861
11862#ifdef MS_WINDOWS
11863
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011864static int
11865ScandirIterator_is_closed(ScandirIterator *iterator)
11866{
11867 return iterator->handle == INVALID_HANDLE_VALUE;
11868}
11869
Victor Stinner6036e442015-03-08 01:58:04 +010011870static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011871ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011872{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011873 HANDLE handle = iterator->handle;
11874
11875 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011876 return;
11877
Victor Stinner6036e442015-03-08 01:58:04 +010011878 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011879 Py_BEGIN_ALLOW_THREADS
11880 FindClose(handle);
11881 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011882}
11883
11884static PyObject *
11885ScandirIterator_iternext(ScandirIterator *iterator)
11886{
11887 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11888 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011889 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011890
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011891 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011892 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011893 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011894
11895 while (1) {
11896 if (!iterator->first_time) {
11897 Py_BEGIN_ALLOW_THREADS
11898 success = FindNextFileW(iterator->handle, file_data);
11899 Py_END_ALLOW_THREADS
11900 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011901 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011902 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011903 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011904 break;
11905 }
11906 }
11907 iterator->first_time = 0;
11908
11909 /* Skip over . and .. */
11910 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011911 wcscmp(file_data->cFileName, L"..") != 0) {
11912 entry = DirEntry_from_find_data(&iterator->path, file_data);
11913 if (!entry)
11914 break;
11915 return entry;
11916 }
Victor Stinner6036e442015-03-08 01:58:04 +010011917
11918 /* Loop till we get a non-dot directory or finish iterating */
11919 }
11920
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011921 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011922 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011923 return NULL;
11924}
11925
11926#else /* POSIX */
11927
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011928static int
11929ScandirIterator_is_closed(ScandirIterator *iterator)
11930{
11931 return !iterator->dirp;
11932}
11933
Victor Stinner6036e442015-03-08 01:58:04 +010011934static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011935ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011936{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011937 DIR *dirp = iterator->dirp;
11938
11939 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011940 return;
11941
Victor Stinner6036e442015-03-08 01:58:04 +010011942 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011943 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011944#ifdef HAVE_FDOPENDIR
11945 if (iterator->path.fd != -1)
11946 rewinddir(dirp);
11947#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011948 closedir(dirp);
11949 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011950 return;
11951}
11952
11953static PyObject *
11954ScandirIterator_iternext(ScandirIterator *iterator)
11955{
11956 struct dirent *direntp;
11957 Py_ssize_t name_len;
11958 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011959 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011960
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011961 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011962 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011963 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011964
11965 while (1) {
11966 errno = 0;
11967 Py_BEGIN_ALLOW_THREADS
11968 direntp = readdir(iterator->dirp);
11969 Py_END_ALLOW_THREADS
11970
11971 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011972 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011973 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011974 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011975 break;
11976 }
11977
11978 /* Skip over . and .. */
11979 name_len = NAMLEN(direntp);
11980 is_dot = direntp->d_name[0] == '.' &&
11981 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11982 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011983 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011984 name_len, direntp->d_ino
11985#ifdef HAVE_DIRENT_D_TYPE
11986 , direntp->d_type
11987#endif
11988 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011989 if (!entry)
11990 break;
11991 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011992 }
11993
11994 /* Loop till we get a non-dot directory or finish iterating */
11995 }
11996
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011997 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011998 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011999 return NULL;
12000}
12001
12002#endif
12003
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012004static PyObject *
12005ScandirIterator_close(ScandirIterator *self, PyObject *args)
12006{
12007 ScandirIterator_closedir(self);
12008 Py_RETURN_NONE;
12009}
12010
12011static PyObject *
12012ScandirIterator_enter(PyObject *self, PyObject *args)
12013{
12014 Py_INCREF(self);
12015 return self;
12016}
12017
12018static PyObject *
12019ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12020{
12021 ScandirIterator_closedir(self);
12022 Py_RETURN_NONE;
12023}
12024
Victor Stinner6036e442015-03-08 01:58:04 +010012025static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012026ScandirIterator_finalize(ScandirIterator *iterator)
12027{
12028 PyObject *error_type, *error_value, *error_traceback;
12029
12030 /* Save the current exception, if any. */
12031 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12032
12033 if (!ScandirIterator_is_closed(iterator)) {
12034 ScandirIterator_closedir(iterator);
12035
12036 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12037 "unclosed scandir iterator %R", iterator)) {
12038 /* Spurious errors can appear at shutdown */
12039 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12040 PyErr_WriteUnraisable((PyObject *) iterator);
12041 }
12042 }
12043 }
12044
Victor Stinner7bfa4092016-03-23 00:43:54 +010012045 path_cleanup(&iterator->path);
12046
12047 /* Restore the saved exception. */
12048 PyErr_Restore(error_type, error_value, error_traceback);
12049}
12050
12051static void
Victor Stinner6036e442015-03-08 01:58:04 +010012052ScandirIterator_dealloc(ScandirIterator *iterator)
12053{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012054 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12055 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012056
Victor Stinner6036e442015-03-08 01:58:04 +010012057 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12058}
12059
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012060static PyMethodDef ScandirIterator_methods[] = {
12061 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12062 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12063 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12064 {NULL}
12065};
12066
Benjamin Peterson5646de42015-04-12 17:56:34 -040012067static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012068 PyVarObject_HEAD_INIT(NULL, 0)
12069 MODNAME ".ScandirIterator", /* tp_name */
12070 sizeof(ScandirIterator), /* tp_basicsize */
12071 0, /* tp_itemsize */
12072 /* methods */
12073 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12074 0, /* tp_print */
12075 0, /* tp_getattr */
12076 0, /* tp_setattr */
12077 0, /* tp_compare */
12078 0, /* tp_repr */
12079 0, /* tp_as_number */
12080 0, /* tp_as_sequence */
12081 0, /* tp_as_mapping */
12082 0, /* tp_hash */
12083 0, /* tp_call */
12084 0, /* tp_str */
12085 0, /* tp_getattro */
12086 0, /* tp_setattro */
12087 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012088 Py_TPFLAGS_DEFAULT
12089 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012090 0, /* tp_doc */
12091 0, /* tp_traverse */
12092 0, /* tp_clear */
12093 0, /* tp_richcompare */
12094 0, /* tp_weaklistoffset */
12095 PyObject_SelfIter, /* tp_iter */
12096 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012097 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012098 0, /* tp_members */
12099 0, /* tp_getset */
12100 0, /* tp_base */
12101 0, /* tp_dict */
12102 0, /* tp_descr_get */
12103 0, /* tp_descr_set */
12104 0, /* tp_dictoffset */
12105 0, /* tp_init */
12106 0, /* tp_alloc */
12107 0, /* tp_new */
12108 0, /* tp_free */
12109 0, /* tp_is_gc */
12110 0, /* tp_bases */
12111 0, /* tp_mro */
12112 0, /* tp_cache */
12113 0, /* tp_subclasses */
12114 0, /* tp_weaklist */
12115 0, /* tp_del */
12116 0, /* tp_version_tag */
12117 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012118};
12119
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012120/*[clinic input]
12121os.scandir
12122
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012123 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012124
12125Return an iterator of DirEntry objects for given path.
12126
12127path can be specified as either str, bytes or path-like object. If path
12128is bytes, the names of yielded DirEntry objects will also be bytes; in
12129all other circumstances they will be str.
12130
12131If path is None, uses the path='.'.
12132[clinic start generated code]*/
12133
Victor Stinner6036e442015-03-08 01:58:04 +010012134static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012135os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012136/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012137{
12138 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012139#ifdef MS_WINDOWS
12140 wchar_t *path_strW;
12141#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012142 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012143#ifdef HAVE_FDOPENDIR
12144 int fd = -1;
12145#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012146#endif
12147
12148 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12149 if (!iterator)
12150 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012151
12152#ifdef MS_WINDOWS
12153 iterator->handle = INVALID_HANDLE_VALUE;
12154#else
12155 iterator->dirp = NULL;
12156#endif
12157
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012158 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012159 /* Move the ownership to iterator->path */
12160 path->object = NULL;
12161 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012162
12163#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012164 iterator->first_time = 1;
12165
12166 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12167 if (!path_strW)
12168 goto error;
12169
12170 Py_BEGIN_ALLOW_THREADS
12171 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12172 Py_END_ALLOW_THREADS
12173
12174 PyMem_Free(path_strW);
12175
12176 if (iterator->handle == INVALID_HANDLE_VALUE) {
12177 path_error(&iterator->path);
12178 goto error;
12179 }
12180#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012181 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012182#ifdef HAVE_FDOPENDIR
12183 if (path->fd != -1) {
12184 /* closedir() closes the FD, so we duplicate it */
12185 fd = _Py_dup(path->fd);
12186 if (fd == -1)
12187 goto error;
12188
12189 Py_BEGIN_ALLOW_THREADS
12190 iterator->dirp = fdopendir(fd);
12191 Py_END_ALLOW_THREADS
12192 }
12193 else
12194#endif
12195 {
12196 if (iterator->path.narrow)
12197 path_str = iterator->path.narrow;
12198 else
12199 path_str = ".";
12200
12201 Py_BEGIN_ALLOW_THREADS
12202 iterator->dirp = opendir(path_str);
12203 Py_END_ALLOW_THREADS
12204 }
Victor Stinner6036e442015-03-08 01:58:04 +010012205
12206 if (!iterator->dirp) {
12207 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012208#ifdef HAVE_FDOPENDIR
12209 if (fd != -1) {
12210 Py_BEGIN_ALLOW_THREADS
12211 close(fd);
12212 Py_END_ALLOW_THREADS
12213 }
12214#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012215 goto error;
12216 }
12217#endif
12218
12219 return (PyObject *)iterator;
12220
12221error:
12222 Py_DECREF(iterator);
12223 return NULL;
12224}
12225
Ethan Furman410ef8e2016-06-04 12:06:26 -070012226/*
12227 Return the file system path representation of the object.
12228
12229 If the object is str or bytes, then allow it to pass through with
12230 an incremented refcount. If the object defines __fspath__(), then
12231 return the result of that method. All other types raise a TypeError.
12232*/
12233PyObject *
12234PyOS_FSPath(PyObject *path)
12235{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012236 /* For error message reasons, this function is manually inlined in
12237 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012238 _Py_IDENTIFIER(__fspath__);
12239 PyObject *func = NULL;
12240 PyObject *path_repr = NULL;
12241
12242 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12243 Py_INCREF(path);
12244 return path;
12245 }
12246
12247 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12248 if (NULL == func) {
12249 return PyErr_Format(PyExc_TypeError,
12250 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012251 "not %.200s",
12252 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012253 }
12254
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012255 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012256 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012257 if (NULL == path_repr) {
12258 return NULL;
12259 }
12260
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012261 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12262 PyErr_Format(PyExc_TypeError,
12263 "expected %.200s.__fspath__() to return str or bytes, "
12264 "not %.200s", Py_TYPE(path)->tp_name,
12265 Py_TYPE(path_repr)->tp_name);
12266 Py_DECREF(path_repr);
12267 return NULL;
12268 }
12269
Ethan Furman410ef8e2016-06-04 12:06:26 -070012270 return path_repr;
12271}
12272
12273/*[clinic input]
12274os.fspath
12275
12276 path: object
12277
12278Return the file system path representation of the object.
12279
Brett Cannonb4f43e92016-06-09 14:32:08 -070012280If the object is str or bytes, then allow it to pass through as-is. If the
12281object defines __fspath__(), then return the result of that method. All other
12282types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012283[clinic start generated code]*/
12284
12285static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012286os_fspath_impl(PyObject *module, PyObject *path)
12287/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012288{
12289 return PyOS_FSPath(path);
12290}
Victor Stinner6036e442015-03-08 01:58:04 +010012291
Victor Stinner9b1f4742016-09-06 16:18:52 -070012292#ifdef HAVE_GETRANDOM_SYSCALL
12293/*[clinic input]
12294os.getrandom
12295
12296 size: Py_ssize_t
12297 flags: int=0
12298
12299Obtain a series of random bytes.
12300[clinic start generated code]*/
12301
12302static PyObject *
12303os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12304/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12305{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012306 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012307 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012308
12309 if (size < 0) {
12310 errno = EINVAL;
12311 return posix_error();
12312 }
12313
Victor Stinnerec2319c2016-09-20 23:00:59 +020012314 bytes = PyBytes_FromStringAndSize(NULL, size);
12315 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012316 PyErr_NoMemory();
12317 return NULL;
12318 }
12319
12320 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012321 n = syscall(SYS_getrandom,
12322 PyBytes_AS_STRING(bytes),
12323 PyBytes_GET_SIZE(bytes),
12324 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012325 if (n < 0 && errno == EINTR) {
12326 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012327 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012328 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012329
12330 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012331 continue;
12332 }
12333 break;
12334 }
12335
12336 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012337 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012338 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012339 }
12340
Victor Stinnerec2319c2016-09-20 23:00:59 +020012341 if (n != size) {
12342 _PyBytes_Resize(&bytes, n);
12343 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012344
12345 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012346
12347error:
12348 Py_DECREF(bytes);
12349 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012350}
12351#endif /* HAVE_GETRANDOM_SYSCALL */
12352
Larry Hastings31826802013-10-19 00:09:25 -070012353
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012354static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012355
12356 OS_STAT_METHODDEF
12357 OS_ACCESS_METHODDEF
12358 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012359 OS_CHDIR_METHODDEF
12360 OS_CHFLAGS_METHODDEF
12361 OS_CHMOD_METHODDEF
12362 OS_FCHMOD_METHODDEF
12363 OS_LCHMOD_METHODDEF
12364 OS_CHOWN_METHODDEF
12365 OS_FCHOWN_METHODDEF
12366 OS_LCHOWN_METHODDEF
12367 OS_LCHFLAGS_METHODDEF
12368 OS_CHROOT_METHODDEF
12369 OS_CTERMID_METHODDEF
12370 OS_GETCWD_METHODDEF
12371 OS_GETCWDB_METHODDEF
12372 OS_LINK_METHODDEF
12373 OS_LISTDIR_METHODDEF
12374 OS_LSTAT_METHODDEF
12375 OS_MKDIR_METHODDEF
12376 OS_NICE_METHODDEF
12377 OS_GETPRIORITY_METHODDEF
12378 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012379#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012380 {"readlink", (PyCFunction)posix_readlink,
12381 METH_VARARGS | METH_KEYWORDS,
12382 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012383#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012384#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012385 {"readlink", (PyCFunction)win_readlink,
12386 METH_VARARGS | METH_KEYWORDS,
12387 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012388#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012389 OS_RENAME_METHODDEF
12390 OS_REPLACE_METHODDEF
12391 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012392 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012393 OS_SYMLINK_METHODDEF
12394 OS_SYSTEM_METHODDEF
12395 OS_UMASK_METHODDEF
12396 OS_UNAME_METHODDEF
12397 OS_UNLINK_METHODDEF
12398 OS_REMOVE_METHODDEF
12399 OS_UTIME_METHODDEF
12400 OS_TIMES_METHODDEF
12401 OS__EXIT_METHODDEF
12402 OS_EXECV_METHODDEF
12403 OS_EXECVE_METHODDEF
12404 OS_SPAWNV_METHODDEF
12405 OS_SPAWNVE_METHODDEF
12406 OS_FORK1_METHODDEF
12407 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012408 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012409 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12410 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12411 OS_SCHED_GETPARAM_METHODDEF
12412 OS_SCHED_GETSCHEDULER_METHODDEF
12413 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12414 OS_SCHED_SETPARAM_METHODDEF
12415 OS_SCHED_SETSCHEDULER_METHODDEF
12416 OS_SCHED_YIELD_METHODDEF
12417 OS_SCHED_SETAFFINITY_METHODDEF
12418 OS_SCHED_GETAFFINITY_METHODDEF
12419 OS_OPENPTY_METHODDEF
12420 OS_FORKPTY_METHODDEF
12421 OS_GETEGID_METHODDEF
12422 OS_GETEUID_METHODDEF
12423 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012424#ifdef HAVE_GETGROUPLIST
12425 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12426#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012427 OS_GETGROUPS_METHODDEF
12428 OS_GETPID_METHODDEF
12429 OS_GETPGRP_METHODDEF
12430 OS_GETPPID_METHODDEF
12431 OS_GETUID_METHODDEF
12432 OS_GETLOGIN_METHODDEF
12433 OS_KILL_METHODDEF
12434 OS_KILLPG_METHODDEF
12435 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012436#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012437 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012438#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012439 OS_SETUID_METHODDEF
12440 OS_SETEUID_METHODDEF
12441 OS_SETREUID_METHODDEF
12442 OS_SETGID_METHODDEF
12443 OS_SETEGID_METHODDEF
12444 OS_SETREGID_METHODDEF
12445 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012446#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012447 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012448#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012449 OS_GETPGID_METHODDEF
12450 OS_SETPGRP_METHODDEF
12451 OS_WAIT_METHODDEF
12452 OS_WAIT3_METHODDEF
12453 OS_WAIT4_METHODDEF
12454 OS_WAITID_METHODDEF
12455 OS_WAITPID_METHODDEF
12456 OS_GETSID_METHODDEF
12457 OS_SETSID_METHODDEF
12458 OS_SETPGID_METHODDEF
12459 OS_TCGETPGRP_METHODDEF
12460 OS_TCSETPGRP_METHODDEF
12461 OS_OPEN_METHODDEF
12462 OS_CLOSE_METHODDEF
12463 OS_CLOSERANGE_METHODDEF
12464 OS_DEVICE_ENCODING_METHODDEF
12465 OS_DUP_METHODDEF
12466 OS_DUP2_METHODDEF
12467 OS_LOCKF_METHODDEF
12468 OS_LSEEK_METHODDEF
12469 OS_READ_METHODDEF
12470 OS_READV_METHODDEF
12471 OS_PREAD_METHODDEF
12472 OS_WRITE_METHODDEF
12473 OS_WRITEV_METHODDEF
12474 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012475#ifdef HAVE_SENDFILE
12476 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12477 posix_sendfile__doc__},
12478#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012479 OS_FSTAT_METHODDEF
12480 OS_ISATTY_METHODDEF
12481 OS_PIPE_METHODDEF
12482 OS_PIPE2_METHODDEF
12483 OS_MKFIFO_METHODDEF
12484 OS_MKNOD_METHODDEF
12485 OS_MAJOR_METHODDEF
12486 OS_MINOR_METHODDEF
12487 OS_MAKEDEV_METHODDEF
12488 OS_FTRUNCATE_METHODDEF
12489 OS_TRUNCATE_METHODDEF
12490 OS_POSIX_FALLOCATE_METHODDEF
12491 OS_POSIX_FADVISE_METHODDEF
12492 OS_PUTENV_METHODDEF
12493 OS_UNSETENV_METHODDEF
12494 OS_STRERROR_METHODDEF
12495 OS_FCHDIR_METHODDEF
12496 OS_FSYNC_METHODDEF
12497 OS_SYNC_METHODDEF
12498 OS_FDATASYNC_METHODDEF
12499 OS_WCOREDUMP_METHODDEF
12500 OS_WIFCONTINUED_METHODDEF
12501 OS_WIFSTOPPED_METHODDEF
12502 OS_WIFSIGNALED_METHODDEF
12503 OS_WIFEXITED_METHODDEF
12504 OS_WEXITSTATUS_METHODDEF
12505 OS_WTERMSIG_METHODDEF
12506 OS_WSTOPSIG_METHODDEF
12507 OS_FSTATVFS_METHODDEF
12508 OS_STATVFS_METHODDEF
12509 OS_CONFSTR_METHODDEF
12510 OS_SYSCONF_METHODDEF
12511 OS_FPATHCONF_METHODDEF
12512 OS_PATHCONF_METHODDEF
12513 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012514 OS__GETFULLPATHNAME_METHODDEF
12515 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012516 OS__GETDISKUSAGE_METHODDEF
12517 OS__GETFINALPATHNAME_METHODDEF
12518 OS__GETVOLUMEPATHNAME_METHODDEF
12519 OS_GETLOADAVG_METHODDEF
12520 OS_URANDOM_METHODDEF
12521 OS_SETRESUID_METHODDEF
12522 OS_SETRESGID_METHODDEF
12523 OS_GETRESUID_METHODDEF
12524 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012525
Larry Hastings2f936352014-08-05 14:04:04 +100012526 OS_GETXATTR_METHODDEF
12527 OS_SETXATTR_METHODDEF
12528 OS_REMOVEXATTR_METHODDEF
12529 OS_LISTXATTR_METHODDEF
12530
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012531#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12532 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12533#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012534 OS_CPU_COUNT_METHODDEF
12535 OS_GET_INHERITABLE_METHODDEF
12536 OS_SET_INHERITABLE_METHODDEF
12537 OS_GET_HANDLE_INHERITABLE_METHODDEF
12538 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012539#ifndef MS_WINDOWS
12540 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12541 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12542#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012543 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012544 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012545 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012547};
12548
12549
Brian Curtin52173d42010-12-02 18:29:18 +000012550#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012551static int
Brian Curtin52173d42010-12-02 18:29:18 +000012552enable_symlink()
12553{
12554 HANDLE tok;
12555 TOKEN_PRIVILEGES tok_priv;
12556 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012557
12558 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012559 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012560
12561 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012562 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012563
12564 tok_priv.PrivilegeCount = 1;
12565 tok_priv.Privileges[0].Luid = luid;
12566 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12567
12568 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12569 sizeof(TOKEN_PRIVILEGES),
12570 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012571 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012572
Brian Curtin3b4499c2010-12-28 14:31:47 +000012573 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12574 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012575}
12576#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12577
Barry Warsaw4a342091996-12-19 23:50:02 +000012578static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012580{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012581#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012583#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012584#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012586#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012587#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012589#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012590#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012592#endif
Fred Drakec9680921999-12-13 16:37:25 +000012593#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012595#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012596#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012598#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012599#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012601#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012602#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012604#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012605#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012606 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012607#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012608#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012609 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012610#endif
12611#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012612 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012613#endif
12614#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012615 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012616#endif
12617#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012618 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012619#endif
12620#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012622#endif
12623#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012624 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012625#endif
12626#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012628#endif
12629#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012630 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012631#endif
12632#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012633 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012634#endif
12635#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012636 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012637#endif
12638#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012639 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012640#endif
12641#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012643#endif
12644#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012645 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012646#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012647#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012648 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012649#endif
12650#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012651 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012652#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012653#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012654 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012655#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012656#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012657 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012658#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012659#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012660#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012662#endif
12663#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012665#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012666#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012667#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012669#endif
12670#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012672#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012673#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012675#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012676#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012678#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012679#ifdef O_TMPFILE
12680 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12681#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012682#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012684#endif
12685#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012687#endif
12688#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012690#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012691#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012693#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012694#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012696#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012697
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012698
Jesus Cea94363612012-06-22 18:32:07 +020012699#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012701#endif
12702#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012704#endif
12705
Tim Peters5aa91602002-01-30 05:46:57 +000012706/* MS Windows */
12707#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012708 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012709 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012710#endif
12711#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012712 /* Optimize for short life (keep in memory). */
12713 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012715#endif
12716#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012717 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012718 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012719#endif
12720#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012721 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012722 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012723#endif
12724#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012725 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012727#endif
12728
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012729/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012730#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012731 /* Send a SIGIO signal whenever input or output
12732 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012733 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012734#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012735#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012736 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012738#endif
12739#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012740 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012742#endif
12743#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012744 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012745 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012746#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012747#ifdef O_NOLINKS
12748 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012750#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012751#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012752 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012754#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012755
Victor Stinner8c62be82010-05-06 00:08:46 +000012756 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012757#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012759#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012760#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012762#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012763#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012764 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012765#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012766#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012768#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012769#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012771#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012772#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012774#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012775#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012777#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012778#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012780#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012781#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012783#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012784#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012786#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012787#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012789#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012790#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012792#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012793#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012795#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012796#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012798#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012799#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012801#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012802#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012804#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012805#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012806 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012807#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012808
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012809 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012810#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012812#endif /* ST_RDONLY */
12813#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012814 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012815#endif /* ST_NOSUID */
12816
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012817 /* GNU extensions */
12818#ifdef ST_NODEV
12819 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12820#endif /* ST_NODEV */
12821#ifdef ST_NOEXEC
12822 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12823#endif /* ST_NOEXEC */
12824#ifdef ST_SYNCHRONOUS
12825 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12826#endif /* ST_SYNCHRONOUS */
12827#ifdef ST_MANDLOCK
12828 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12829#endif /* ST_MANDLOCK */
12830#ifdef ST_WRITE
12831 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12832#endif /* ST_WRITE */
12833#ifdef ST_APPEND
12834 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12835#endif /* ST_APPEND */
12836#ifdef ST_NOATIME
12837 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12838#endif /* ST_NOATIME */
12839#ifdef ST_NODIRATIME
12840 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12841#endif /* ST_NODIRATIME */
12842#ifdef ST_RELATIME
12843 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12844#endif /* ST_RELATIME */
12845
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012846 /* FreeBSD sendfile() constants */
12847#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012849#endif
12850#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012852#endif
12853#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012855#endif
12856
Ross Lagerwall7807c352011-03-17 20:20:30 +020012857 /* constants for posix_fadvise */
12858#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012859 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012860#endif
12861#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012862 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012863#endif
12864#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012865 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012866#endif
12867#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012868 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012869#endif
12870#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012871 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012872#endif
12873#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012874 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012875#endif
12876
12877 /* constants for waitid */
12878#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12880 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12881 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012882#endif
12883#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012885#endif
12886#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012888#endif
12889#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012891#endif
12892#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012894#endif
12895#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012897#endif
12898#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012900#endif
12901#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012903#endif
12904
12905 /* constants for lockf */
12906#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012907 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012908#endif
12909#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012910 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012911#endif
12912#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012914#endif
12915#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012916 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012917#endif
12918
Guido van Rossum246bc171999-02-01 23:54:31 +000012919#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012920 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12921 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12922 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12923 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12924 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012925#endif
12926
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012927#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012928#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012929 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012930#endif
12931#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012932 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012933#endif
12934#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012935 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012936#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012937#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012938 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012939#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012940#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012941 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012942#endif
12943#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012944 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012945#endif
12946#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012947 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012948#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012949#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012950 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012951#endif
12952#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012953 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012954#endif
12955#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012956 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012957#endif
12958#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012959 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012960#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012961#endif
12962
Benjamin Peterson9428d532011-09-14 11:45:52 -040012963#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012964 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12965 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12966 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012967#endif
12968
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012969#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012970 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012971#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012972#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012973 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012974#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012975#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012976 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012977#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012978#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012980#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012981#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012982 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012983#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012984#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012985 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012986#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012987#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012988 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012989#endif
12990
Victor Stinner9b1f4742016-09-06 16:18:52 -070012991#ifdef HAVE_GETRANDOM_SYSCALL
12992 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12993 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12994#endif
12995
Victor Stinner8c62be82010-05-06 00:08:46 +000012996 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012997}
12998
12999
Martin v. Löwis1a214512008-06-11 05:26:20 +000013000static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 PyModuleDef_HEAD_INIT,
13002 MODNAME,
13003 posix__doc__,
13004 -1,
13005 posix_methods,
13006 NULL,
13007 NULL,
13008 NULL,
13009 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013010};
13011
13012
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013013static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013014
13015#ifdef HAVE_FACCESSAT
13016 "HAVE_FACCESSAT",
13017#endif
13018
13019#ifdef HAVE_FCHDIR
13020 "HAVE_FCHDIR",
13021#endif
13022
13023#ifdef HAVE_FCHMOD
13024 "HAVE_FCHMOD",
13025#endif
13026
13027#ifdef HAVE_FCHMODAT
13028 "HAVE_FCHMODAT",
13029#endif
13030
13031#ifdef HAVE_FCHOWN
13032 "HAVE_FCHOWN",
13033#endif
13034
Larry Hastings00964ed2013-08-12 13:49:30 -040013035#ifdef HAVE_FCHOWNAT
13036 "HAVE_FCHOWNAT",
13037#endif
13038
Larry Hastings9cf065c2012-06-22 16:30:09 -070013039#ifdef HAVE_FEXECVE
13040 "HAVE_FEXECVE",
13041#endif
13042
13043#ifdef HAVE_FDOPENDIR
13044 "HAVE_FDOPENDIR",
13045#endif
13046
Georg Brandl306336b2012-06-24 12:55:33 +020013047#ifdef HAVE_FPATHCONF
13048 "HAVE_FPATHCONF",
13049#endif
13050
Larry Hastings9cf065c2012-06-22 16:30:09 -070013051#ifdef HAVE_FSTATAT
13052 "HAVE_FSTATAT",
13053#endif
13054
13055#ifdef HAVE_FSTATVFS
13056 "HAVE_FSTATVFS",
13057#endif
13058
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013059#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013060 "HAVE_FTRUNCATE",
13061#endif
13062
Larry Hastings9cf065c2012-06-22 16:30:09 -070013063#ifdef HAVE_FUTIMENS
13064 "HAVE_FUTIMENS",
13065#endif
13066
13067#ifdef HAVE_FUTIMES
13068 "HAVE_FUTIMES",
13069#endif
13070
13071#ifdef HAVE_FUTIMESAT
13072 "HAVE_FUTIMESAT",
13073#endif
13074
13075#ifdef HAVE_LINKAT
13076 "HAVE_LINKAT",
13077#endif
13078
13079#ifdef HAVE_LCHFLAGS
13080 "HAVE_LCHFLAGS",
13081#endif
13082
13083#ifdef HAVE_LCHMOD
13084 "HAVE_LCHMOD",
13085#endif
13086
13087#ifdef HAVE_LCHOWN
13088 "HAVE_LCHOWN",
13089#endif
13090
13091#ifdef HAVE_LSTAT
13092 "HAVE_LSTAT",
13093#endif
13094
13095#ifdef HAVE_LUTIMES
13096 "HAVE_LUTIMES",
13097#endif
13098
13099#ifdef HAVE_MKDIRAT
13100 "HAVE_MKDIRAT",
13101#endif
13102
13103#ifdef HAVE_MKFIFOAT
13104 "HAVE_MKFIFOAT",
13105#endif
13106
13107#ifdef HAVE_MKNODAT
13108 "HAVE_MKNODAT",
13109#endif
13110
13111#ifdef HAVE_OPENAT
13112 "HAVE_OPENAT",
13113#endif
13114
13115#ifdef HAVE_READLINKAT
13116 "HAVE_READLINKAT",
13117#endif
13118
13119#ifdef HAVE_RENAMEAT
13120 "HAVE_RENAMEAT",
13121#endif
13122
13123#ifdef HAVE_SYMLINKAT
13124 "HAVE_SYMLINKAT",
13125#endif
13126
13127#ifdef HAVE_UNLINKAT
13128 "HAVE_UNLINKAT",
13129#endif
13130
13131#ifdef HAVE_UTIMENSAT
13132 "HAVE_UTIMENSAT",
13133#endif
13134
13135#ifdef MS_WINDOWS
13136 "MS_WINDOWS",
13137#endif
13138
13139 NULL
13140};
13141
13142
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013143PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013144INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013145{
Victor Stinner8c62be82010-05-06 00:08:46 +000013146 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013147 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013148 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013149
Brian Curtin52173d42010-12-02 18:29:18 +000013150#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013151 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013152#endif
13153
Victor Stinner8c62be82010-05-06 00:08:46 +000013154 m = PyModule_Create(&posixmodule);
13155 if (m == NULL)
13156 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013157
Victor Stinner8c62be82010-05-06 00:08:46 +000013158 /* Initialize environ dictionary */
13159 v = convertenviron();
13160 Py_XINCREF(v);
13161 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13162 return NULL;
13163 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013164
Victor Stinner8c62be82010-05-06 00:08:46 +000013165 if (all_ins(m))
13166 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013167
Victor Stinner8c62be82010-05-06 00:08:46 +000013168 if (setup_confname_tables(m))
13169 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013170
Victor Stinner8c62be82010-05-06 00:08:46 +000013171 Py_INCREF(PyExc_OSError);
13172 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013173
Guido van Rossumb3d39562000-01-31 18:41:26 +000013174#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013175 if (posix_putenv_garbage == NULL)
13176 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013177#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013178
Victor Stinner8c62be82010-05-06 00:08:46 +000013179 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013180#if defined(HAVE_WAITID) && !defined(__APPLE__)
13181 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013182 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13183 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013184#endif
13185
Christian Heimes25827622013-10-12 01:27:08 +020013186 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013187 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13188 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13189 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013190 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13191 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013192 structseq_new = StatResultType.tp_new;
13193 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013194
Christian Heimes25827622013-10-12 01:27:08 +020013195 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013196 if (PyStructSequence_InitType2(&StatVFSResultType,
13197 &statvfs_result_desc) < 0)
13198 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013199#ifdef NEED_TICKS_PER_SECOND
13200# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013201 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013202# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013203 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013204# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013205 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013206# endif
13207#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013208
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013209#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013210 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013211 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13212 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013213 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013214#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013215
13216 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013217 if (PyStructSequence_InitType2(&TerminalSizeType,
13218 &TerminalSize_desc) < 0)
13219 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013220
13221 /* initialize scandir types */
13222 if (PyType_Ready(&ScandirIteratorType) < 0)
13223 return NULL;
13224 if (PyType_Ready(&DirEntryType) < 0)
13225 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013226 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013227#if defined(HAVE_WAITID) && !defined(__APPLE__)
13228 Py_INCREF((PyObject*) &WaitidResultType);
13229 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13230#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013231 Py_INCREF((PyObject*) &StatResultType);
13232 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13233 Py_INCREF((PyObject*) &StatVFSResultType);
13234 PyModule_AddObject(m, "statvfs_result",
13235 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013236
13237#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013238 Py_INCREF(&SchedParamType);
13239 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013240#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013241
Larry Hastings605a62d2012-06-24 04:33:36 -070013242 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013243 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13244 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013245 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13246
13247 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013248 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13249 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013250 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13251
Thomas Wouters477c8d52006-05-27 19:21:47 +000013252#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013253 /*
13254 * Step 2 of weak-linking support on Mac OS X.
13255 *
13256 * The code below removes functions that are not available on the
13257 * currently active platform.
13258 *
13259 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013260 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013261 * OSX 10.4.
13262 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013263#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013264 if (fstatvfs == NULL) {
13265 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13266 return NULL;
13267 }
13268 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013269#endif /* HAVE_FSTATVFS */
13270
13271#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013272 if (statvfs == NULL) {
13273 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13274 return NULL;
13275 }
13276 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013277#endif /* HAVE_STATVFS */
13278
13279# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013280 if (lchown == NULL) {
13281 if (PyObject_DelAttrString(m, "lchown") == -1) {
13282 return NULL;
13283 }
13284 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013285#endif /* HAVE_LCHOWN */
13286
13287
13288#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013289
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013290 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013291 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13292
Larry Hastings6fe20b32012-04-19 15:07:49 -070013293 billion = PyLong_FromLong(1000000000);
13294 if (!billion)
13295 return NULL;
13296
Larry Hastings9cf065c2012-06-22 16:30:09 -070013297 /* suppress "function not used" warnings */
13298 {
13299 int ignored;
13300 fd_specified("", -1);
13301 follow_symlinks_specified("", 1);
13302 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13303 dir_fd_converter(Py_None, &ignored);
13304 dir_fd_unavailable(Py_None, &ignored);
13305 }
13306
13307 /*
13308 * provide list of locally available functions
13309 * so os.py can populate support_* lists
13310 */
13311 list = PyList_New(0);
13312 if (!list)
13313 return NULL;
13314 for (trace = have_functions; *trace; trace++) {
13315 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13316 if (!unicode)
13317 return NULL;
13318 if (PyList_Append(list, unicode))
13319 return NULL;
13320 Py_DECREF(unicode);
13321 }
13322 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013323
13324 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013325 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013326
13327 initialized = 1;
13328
Victor Stinner8c62be82010-05-06 00:08:46 +000013329 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013330}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013331
13332#ifdef __cplusplus
13333}
13334#endif