blob: 8f8ba255ec48f6ff5125691767aa7342bad754e9 [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"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020035/* On android API level 21, 'AT_EACCESS' is not declared although
36 * HAVE_FACCESSAT is defined. */
37#ifdef __ANDROID__
38#undef HAVE_FACCESSAT
39#endif
40
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000041#include <stdio.h> /* needed for ctermid() */
42
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#ifdef __cplusplus
44extern "C" {
45#endif
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000048"This module provides access to operating system functionality that is\n\
49standardized by the C Standard and the POSIX standard (a thinly\n\
50disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000053
Ross Lagerwall4d076da2011-03-18 06:56:53 +020054#ifdef HAVE_SYS_UIO_H
55#include <sys/uio.h>
56#endif
57
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000059#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060#endif /* HAVE_SYS_TYPES_H */
61
62#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000065
Guido van Rossum36bc6801995-06-14 22:54:23 +000066#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000067#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000068#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000071#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000073
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#ifdef HAVE_FCNTL_H
75#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000076#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Guido van Rossuma6535fd2001-10-18 19:44:10 +000078#ifdef HAVE_GRP_H
79#include <grp.h>
80#endif
81
Barry Warsaw5676bd12003-01-07 20:57:09 +000082#ifdef HAVE_SYSEXITS_H
83#include <sysexits.h>
84#endif /* HAVE_SYSEXITS_H */
85
Anthony Baxter8a560de2004-10-13 15:30:56 +000086#ifdef HAVE_SYS_LOADAVG_H
87#include <sys/loadavg.h>
88#endif
89
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000090#ifdef HAVE_LANGINFO_H
91#include <langinfo.h>
92#endif
93
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000094#ifdef HAVE_SYS_SENDFILE_H
95#include <sys/sendfile.h>
96#endif
97
Benjamin Peterson94b580d2011-08-02 17:30:04 -050098#ifdef HAVE_SCHED_H
99#include <sched.h>
100#endif
101
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500102#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500103#undef HAVE_SCHED_SETAFFINITY
104#endif
105
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200106#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400107#define USE_XATTRS
108#endif
109
110#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400111#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400112#endif
113
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
115#ifdef HAVE_SYS_SOCKET_H
116#include <sys/socket.h>
117#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#endif
119
Victor Stinner8b905bd2011-10-25 13:34:04 +0200120#ifdef HAVE_DLFCN_H
121#include <dlfcn.h>
122#endif
123
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200124#ifdef __hpux
125#include <sys/mpctl.h>
126#endif
127
128#if defined(__DragonFly__) || \
129 defined(__OpenBSD__) || \
130 defined(__FreeBSD__) || \
131 defined(__NetBSD__) || \
132 defined(__APPLE__)
133#include <sys/sysctl.h>
134#endif
135
Victor Stinner9b1f4742016-09-06 16:18:52 -0700136#ifdef HAVE_LINUX_RANDOM_H
137# include <linux/random.h>
138#endif
139#ifdef HAVE_GETRANDOM_SYSCALL
140# include <sys/syscall.h>
141#endif
142
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100143#if defined(MS_WINDOWS)
144# define TERMSIZE_USE_CONIO
145#elif defined(HAVE_SYS_IOCTL_H)
146# include <sys/ioctl.h>
147# if defined(HAVE_TERMIOS_H)
148# include <termios.h>
149# endif
150# if defined(TIOCGWINSZ)
151# define TERMSIZE_USE_IOCTL
152# endif
153#endif /* MS_WINDOWS */
154
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000156/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#include <process.h>
161#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000163#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000164#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700167#define HAVE_WSPAWNV 1
168#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#define HAVE_SYSTEM 1
171#define HAVE_CWAIT 1
172#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000173#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000174#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175/* Unix functions that the configure script doesn't check for */
176#define HAVE_EXECV 1
177#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000179#define HAVE_FORK1 1
180#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_GETEGID 1
182#define HAVE_GETEUID 1
183#define HAVE_GETGID 1
184#define HAVE_GETPPID 1
185#define HAVE_GETUID 1
186#define HAVE_KILL 1
187#define HAVE_OPENDIR 1
188#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000189#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000193#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000194
Victor Stinnera2f7c002012-02-08 03:36:25 +0100195
Larry Hastings61272b72014-01-07 12:41:53 -0800196/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000197# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800198module os
Larry Hastings61272b72014-01-07 12:41:53 -0800199[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000200/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100201
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000204#if defined(__sgi)&&_COMPILER_VERSION>=700
205/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
206 (default) */
207extern char *ctermid_r(char *);
208#endif
209
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000210#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000214#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#endif
220#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chdir(char *);
222extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int chdir(const char *);
225extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000228/*#ifdef HAVE_FCHMOD
229extern int fchmod(int, mode_t);
230#endif*/
231/*#ifdef HAVE_LCHMOD
232extern int lchmod(const char *, mode_t);
233#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chown(const char *, uid_t, gid_t);
235extern char *getcwd(char *, int);
236extern char *strerror(int);
237extern int link(const char *, const char *);
238extern int rename(const char *, const char *);
239extern int stat(const char *, struct stat *);
240extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000243#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_UTIME_H
252#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000255#ifdef HAVE_SYS_UTIME_H
256#include <sys/utime.h>
257#define HAVE_UTIME_H /* pretend we do for the rest of this file */
258#endif /* HAVE_SYS_UTIME_H */
259
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#ifdef HAVE_SYS_TIMES_H
261#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef HAVE_SYS_PARAM_H
265#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
268#ifdef HAVE_SYS_UTSNAME_H
269#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#define NAMLEN(dirent) strlen((dirent)->d_name)
275#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000276#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#include <direct.h>
278#define NAMLEN(dirent) strlen((dirent)->d_name)
279#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000294#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
301#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100313#ifndef IO_REPARSE_TAG_MOUNT_POINT
314#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000317#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000319#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000320#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000321#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
322#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000323static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000324#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000325#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#if defined(PATH_MAX) && PATH_MAX > 1024
329#define MAXPATHLEN PATH_MAX
330#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000332#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000333#endif /* MAXPATHLEN */
334
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000335#ifdef UNION_WAIT
336/* Emulate some macros on systems that have a union instead of macros */
337
338#ifndef WIFEXITED
339#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
340#endif
341
342#ifndef WEXITSTATUS
343#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
344#endif
345
346#ifndef WTERMSIG
347#define WTERMSIG(u_wait) ((u_wait).w_termsig)
348#endif
349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350#define WAIT_TYPE union wait
351#define WAIT_STATUS_INT(s) (s.w_status)
352
353#else /* !UNION_WAIT */
354#define WAIT_TYPE int
355#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000356#endif /* UNION_WAIT */
357
Greg Wardb48bc172000-03-01 21:51:56 +0000358/* Don't use the "_r" form if we don't need it (also, won't have a
359 prototype for it, at least on Solaris -- maybe others as well?). */
360#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
361#define USE_CTERMID_R
362#endif
363
Fred Drake699f3522000-06-29 21:12:41 +0000364/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000365#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000366#undef FSTAT
367#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200368#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700370# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200371# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800372# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000373#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000376# define FSTAT fstat
377# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000378#endif
379
Tim Peters11b23062003-04-23 02:39:17 +0000380#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#include <sys/mkdev.h>
382#else
383#if defined(MAJOR_IN_SYSMACROS)
384#include <sys/sysmacros.h>
385#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000386#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
387#include <sys/mkdev.h>
388#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000389#endif
Fred Drake699f3522000-06-29 21:12:41 +0000390
Victor Stinner6edddfa2013-11-24 19:22:57 +0100391#define DWORD_MAX 4294967295U
392
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200393#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100394#define INITFUNC PyInit_nt
395#define MODNAME "nt"
396#else
397#define INITFUNC PyInit_posix
398#define MODNAME "posix"
399#endif
400
401#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200402/* defined in fileutils.c */
403PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
404PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
405 ULONG, struct _Py_stat_struct *);
406#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700407
408#ifdef MS_WINDOWS
409static int
410win32_warn_bytes_api()
411{
412 return PyErr_WarnEx(PyExc_DeprecationWarning,
413 "The Windows bytes API has been deprecated, "
414 "use Unicode filenames instead",
415 1);
416}
417#endif
418
419
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200420#ifndef MS_WINDOWS
421PyObject *
422_PyLong_FromUid(uid_t uid)
423{
424 if (uid == (uid_t)-1)
425 return PyLong_FromLong(-1);
426 return PyLong_FromUnsignedLong(uid);
427}
428
429PyObject *
430_PyLong_FromGid(gid_t gid)
431{
432 if (gid == (gid_t)-1)
433 return PyLong_FromLong(-1);
434 return PyLong_FromUnsignedLong(gid);
435}
436
437int
438_Py_Uid_Converter(PyObject *obj, void *p)
439{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700440 uid_t uid;
441 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200442 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200443 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700444 unsigned long uresult;
445
446 index = PyNumber_Index(obj);
447 if (index == NULL) {
448 PyErr_Format(PyExc_TypeError,
449 "uid should be integer, not %.200s",
450 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200451 return 0;
452 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700453
454 /*
455 * Handling uid_t is complicated for two reasons:
456 * * Although uid_t is (always?) unsigned, it still
457 * accepts -1.
458 * * We don't know its size in advance--it may be
459 * bigger than an int, or it may be smaller than
460 * a long.
461 *
462 * So a bit of defensive programming is in order.
463 * Start with interpreting the value passed
464 * in as a signed long and see if it works.
465 */
466
467 result = PyLong_AsLongAndOverflow(index, &overflow);
468
469 if (!overflow) {
470 uid = (uid_t)result;
471
472 if (result == -1) {
473 if (PyErr_Occurred())
474 goto fail;
475 /* It's a legitimate -1, we're done. */
476 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200477 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700478
479 /* Any other negative number is disallowed. */
480 if (result < 0)
481 goto underflow;
482
483 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200484 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700485 (long)uid != result)
486 goto underflow;
487 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200488 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700489
490 if (overflow < 0)
491 goto underflow;
492
493 /*
494 * Okay, the value overflowed a signed long. If it
495 * fits in an *unsigned* long, it may still be okay,
496 * as uid_t may be unsigned long on this platform.
497 */
498 uresult = PyLong_AsUnsignedLong(index);
499 if (PyErr_Occurred()) {
500 if (PyErr_ExceptionMatches(PyExc_OverflowError))
501 goto overflow;
502 goto fail;
503 }
504
505 uid = (uid_t)uresult;
506
507 /*
508 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
509 * but this value would get interpreted as (uid_t)-1 by chown
510 * and its siblings. That's not what the user meant! So we
511 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100512 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 */
514 if (uid == (uid_t)-1)
515 goto overflow;
516
517 /* Ensure the value wasn't truncated. */
518 if (sizeof(uid_t) < sizeof(long) &&
519 (unsigned long)uid != uresult)
520 goto overflow;
521 /* fallthrough */
522
523success:
524 Py_DECREF(index);
525 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 return 1;
527
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200529 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 "uid is less than minimum");
531 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200534 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 "uid is greater than maximum");
536 /* fallthrough */
537
538fail:
539 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200540 return 0;
541}
542
543int
544_Py_Gid_Converter(PyObject *obj, void *p)
545{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700546 gid_t gid;
547 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200548 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200549 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700550 unsigned long uresult;
551
552 index = PyNumber_Index(obj);
553 if (index == NULL) {
554 PyErr_Format(PyExc_TypeError,
555 "gid should be integer, not %.200s",
556 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200557 return 0;
558 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700559
560 /*
561 * Handling gid_t is complicated for two reasons:
562 * * Although gid_t is (always?) unsigned, it still
563 * accepts -1.
564 * * We don't know its size in advance--it may be
565 * bigger than an int, or it may be smaller than
566 * a long.
567 *
568 * So a bit of defensive programming is in order.
569 * Start with interpreting the value passed
570 * in as a signed long and see if it works.
571 */
572
573 result = PyLong_AsLongAndOverflow(index, &overflow);
574
575 if (!overflow) {
576 gid = (gid_t)result;
577
578 if (result == -1) {
579 if (PyErr_Occurred())
580 goto fail;
581 /* It's a legitimate -1, we're done. */
582 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200583 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700584
585 /* Any other negative number is disallowed. */
586 if (result < 0) {
587 goto underflow;
588 }
589
590 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592 (long)gid != result)
593 goto underflow;
594 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200595 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700596
597 if (overflow < 0)
598 goto underflow;
599
600 /*
601 * Okay, the value overflowed a signed long. If it
602 * fits in an *unsigned* long, it may still be okay,
603 * as gid_t may be unsigned long on this platform.
604 */
605 uresult = PyLong_AsUnsignedLong(index);
606 if (PyErr_Occurred()) {
607 if (PyErr_ExceptionMatches(PyExc_OverflowError))
608 goto overflow;
609 goto fail;
610 }
611
612 gid = (gid_t)uresult;
613
614 /*
615 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
616 * but this value would get interpreted as (gid_t)-1 by chown
617 * and its siblings. That's not what the user meant! So we
618 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100619 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 */
621 if (gid == (gid_t)-1)
622 goto overflow;
623
624 /* Ensure the value wasn't truncated. */
625 if (sizeof(gid_t) < sizeof(long) &&
626 (unsigned long)gid != uresult)
627 goto overflow;
628 /* fallthrough */
629
630success:
631 Py_DECREF(index);
632 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200633 return 1;
634
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 "gid is less than minimum");
638 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642 "gid is greater than maximum");
643 /* fallthrough */
644
645fail:
646 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200647 return 0;
648}
649#endif /* MS_WINDOWS */
650
651
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700652#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800653
654
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200655#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
656static int
657_Py_Dev_Converter(PyObject *obj, void *p)
658{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200659 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200660 if (PyErr_Occurred())
661 return 0;
662 return 1;
663}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800664#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200665
666
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400668/*
669 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
670 * without the int cast, the value gets interpreted as uint (4291925331),
671 * which doesn't play nicely with all the initializer lines in this file that
672 * look like this:
673 * int dir_fd = DEFAULT_DIR_FD;
674 */
675#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700676#else
677#define DEFAULT_DIR_FD (-100)
678#endif
679
680static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300681_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200682{
683 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684 long long_value;
685
686 PyObject *index = PyNumber_Index(o);
687 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 return 0;
689 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300691 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 long_value = PyLong_AsLongAndOverflow(index, &overflow);
693 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300694 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200695 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700696 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 return 0;
699 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200700 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700702 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700703 return 0;
704 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700705
Larry Hastings9cf065c2012-06-22 16:30:09 -0700706 *p = (int)long_value;
707 return 1;
708}
709
710static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200711dir_fd_converter(PyObject *o, void *p)
712{
713 if (o == Py_None) {
714 *(int *)p = DEFAULT_DIR_FD;
715 return 1;
716 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300717 else if (PyIndex_Check(o)) {
718 return _fd_converter(o, (int *)p);
719 }
720 else {
721 PyErr_Format(PyExc_TypeError,
722 "argument should be integer or None, not %.200s",
723 Py_TYPE(o)->tp_name);
724 return 0;
725 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700726}
727
728
Larry Hastings9cf065c2012-06-22 16:30:09 -0700729/*
730 * A PyArg_ParseTuple "converter" function
731 * that handles filesystem paths in the manner
732 * preferred by the os module.
733 *
734 * path_converter accepts (Unicode) strings and their
735 * subclasses, and bytes and their subclasses. What
736 * it does with the argument depends on the platform:
737 *
738 * * On Windows, if we get a (Unicode) string we
739 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700740 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700741 *
742 * * On all other platforms, strings are encoded
743 * to bytes using PyUnicode_FSConverter, then we
744 * extract the char * from the bytes object and
745 * return that.
746 *
747 * path_converter also optionally accepts signed
748 * integers (representing open file descriptors) instead
749 * of path strings.
750 *
751 * Input fields:
752 * path.nullable
753 * If nonzero, the path is permitted to be None.
754 * path.allow_fd
755 * If nonzero, the path is permitted to be a file handle
756 * (a signed int) instead of a string.
757 * path.function_name
758 * If non-NULL, path_converter will use that as the name
759 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700760 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761 * path.argument_name
762 * If non-NULL, path_converter will use that as the name
763 * of the parameter in error messages.
764 * (If path.argument_name is NULL it uses "path".)
765 *
766 * Output fields:
767 * path.wide
768 * Points to the path if it was expressed as Unicode
769 * and was not encoded. (Only used on Windows.)
770 * path.narrow
771 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700772 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000773 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700774 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700775 * path.fd
776 * Contains a file descriptor if path.accept_fd was true
777 * and the caller provided a signed integer instead of any
778 * sort of string.
779 *
780 * WARNING: if your "path" parameter is optional, and is
781 * unspecified, path_converter will never get called.
782 * So if you set allow_fd, you *MUST* initialize path.fd = -1
783 * yourself!
784 * path.length
785 * The length of the path in characters, if specified as
786 * a string.
787 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800788 * The original object passed in (if get a PathLike object,
789 * the result of PyOS_FSPath() is treated as the original object).
790 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700791 * path.cleanup
792 * For internal use only. May point to a temporary object.
793 * (Pay no attention to the man behind the curtain.)
794 *
795 * At most one of path.wide or path.narrow will be non-NULL.
796 * If path was None and path.nullable was set,
797 * or if path was an integer and path.allow_fd was set,
798 * both path.wide and path.narrow will be NULL
799 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200800 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700801 * path_converter takes care to not write to the path_t
802 * unless it's successful. However it must reset the
803 * "cleanup" field each time it's called.
804 *
805 * Use as follows:
806 * path_t path;
807 * memset(&path, 0, sizeof(path));
808 * PyArg_ParseTuple(args, "O&", path_converter, &path);
809 * // ... use values from path ...
810 * path_cleanup(&path);
811 *
812 * (Note that if PyArg_Parse fails you don't need to call
813 * path_cleanup(). However it is safe to do so.)
814 */
815typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100816 const char *function_name;
817 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700818 int nullable;
819 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300820 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700821#ifdef MS_WINDOWS
822 BOOL narrow;
823#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300824 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700825#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700826 int fd;
827 Py_ssize_t length;
828 PyObject *object;
829 PyObject *cleanup;
830} path_t;
831
Steve Dowercc16be82016-09-08 10:35:16 -0700832#ifdef MS_WINDOWS
833#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
834 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
835#else
Larry Hastings2f936352014-08-05 14:04:04 +1000836#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
837 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700838#endif
Larry Hastings31826802013-10-19 00:09:25 -0700839
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800841path_cleanup(path_t *path)
842{
843 Py_CLEAR(path->object);
844 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700845}
846
847static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300848path_converter(PyObject *o, void *p)
849{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700850 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800851 PyObject *bytes = NULL;
852 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700853 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300854 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700855#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800856 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700857 const wchar_t *wide;
858#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859
860#define FORMAT_EXCEPTION(exc, fmt) \
861 PyErr_Format(exc, "%s%s" fmt, \
862 path->function_name ? path->function_name : "", \
863 path->function_name ? ": " : "", \
864 path->argument_name ? path->argument_name : "path")
865
866 /* Py_CLEANUP_SUPPORTED support */
867 if (o == NULL) {
868 path_cleanup(path);
869 return 1;
870 }
871
Brett Cannon3f9183b2016-08-26 14:44:48 -0700872 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800873 path->object = path->cleanup = NULL;
874 /* path->object owns a reference to the original object */
875 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300877 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700878 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700879#ifdef MS_WINDOWS
880 path->narrow = FALSE;
881#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700883#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700884 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800885 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700886 }
887
Brett Cannon3f9183b2016-08-26 14:44:48 -0700888 /* Only call this here so that we don't treat the return value of
889 os.fspath() as an fd or buffer. */
890 is_index = path->allow_fd && PyIndex_Check(o);
891 is_buffer = PyObject_CheckBuffer(o);
892 is_bytes = PyBytes_Check(o);
893 is_unicode = PyUnicode_Check(o);
894
895 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
896 /* Inline PyOS_FSPath() for better error messages. */
897 _Py_IDENTIFIER(__fspath__);
898 PyObject *func = NULL;
899
900 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
901 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800902 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700903 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800904 /* still owns a reference to the original object */
905 Py_DECREF(o);
906 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700907 Py_DECREF(func);
908 if (NULL == o) {
909 goto error_exit;
910 }
911 else if (PyUnicode_Check(o)) {
912 is_unicode = 1;
913 }
914 else if (PyBytes_Check(o)) {
915 is_bytes = 1;
916 }
917 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800918 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700919 }
920 }
921
922 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700923#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +0200924 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100925 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800926 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700927 }
Victor Stinner59799a82013-11-13 14:17:30 +0100928 if (length > 32767) {
929 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +0800930 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300932 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300933 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +0800934 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300935 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700936
937 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +0800938 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800940 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300942 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800943 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300944 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945#endif
946 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700947 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300948 bytes = o;
949 Py_INCREF(bytes);
950 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700951 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300952 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
953 "%s%s%s should be %s, not %.200s",
954 path->function_name ? path->function_name : "",
955 path->function_name ? ": " : "",
956 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700957 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
958 "integer or None" :
959 path->allow_fd ? "string, bytes, os.PathLike or integer" :
960 path->nullable ? "string, bytes, os.PathLike or None" :
961 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300962 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800963 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300964 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300965 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800967 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 }
969 }
Steve Dowercc16be82016-09-08 10:35:16 -0700970 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300971 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800972 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300973 }
974 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700975#ifdef MS_WINDOWS
976 path->narrow = FALSE;
977#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300978 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700979#endif
Xiang Zhang04316c42017-01-08 23:26:57 +0800980 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300981 }
982 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800983 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300984 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
985 path->function_name ? path->function_name : "",
986 path->function_name ? ": " : "",
987 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700988 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
989 "integer or None" :
990 path->allow_fd ? "string, bytes, os.PathLike or integer" :
991 path->nullable ? "string, bytes, os.PathLike or None" :
992 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300993 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +0800994 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 }
996
Larry Hastings9cf065c2012-06-22 16:30:09 -0700997 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700998 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200999 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001000 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001001 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002 }
1003
Steve Dowercc16be82016-09-08 10:35:16 -07001004#ifdef MS_WINDOWS
1005 wo = PyUnicode_DecodeFSDefaultAndSize(
1006 narrow,
1007 length
1008 );
1009 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001011 }
1012
Xiang Zhang04316c42017-01-08 23:26:57 +08001013 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001014 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001015 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001016 }
1017 if (length > 32767) {
1018 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001019 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001020 }
1021 if (wcslen(wide) != length) {
1022 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001023 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001024 }
1025 path->wide = wide;
1026 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001027 path->cleanup = wo;
1028 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001029#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001030 path->wide = NULL;
1031 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001032 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001033 /* Still a reference owned by path->object, don't have to
1034 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001035 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001036 }
1037 else {
1038 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001039 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001040#endif
1041 path->fd = -1;
1042
1043 success_exit:
1044 path->length = length;
1045 path->object = o;
1046 return Py_CLEANUP_SUPPORTED;
1047
1048 error_exit:
1049 Py_XDECREF(o);
1050 Py_XDECREF(bytes);
1051#ifdef MS_WINDOWS
1052 Py_XDECREF(wo);
1053#endif
1054 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055}
1056
1057static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001058argument_unavailable_error(const char *function_name, const char *argument_name)
1059{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001060 PyErr_Format(PyExc_NotImplementedError,
1061 "%s%s%s unavailable on this platform",
1062 (function_name != NULL) ? function_name : "",
1063 (function_name != NULL) ? ": ": "",
1064 argument_name);
1065}
1066
1067static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001068dir_fd_unavailable(PyObject *o, void *p)
1069{
1070 int dir_fd;
1071 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001072 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001073 if (dir_fd != DEFAULT_DIR_FD) {
1074 argument_unavailable_error(NULL, "dir_fd");
1075 return 0;
1076 }
1077 *(int *)p = dir_fd;
1078 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079}
1080
1081static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001082fd_specified(const char *function_name, int fd)
1083{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 if (fd == -1)
1085 return 0;
1086
1087 argument_unavailable_error(function_name, "fd");
1088 return 1;
1089}
1090
1091static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001092follow_symlinks_specified(const char *function_name, int follow_symlinks)
1093{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001094 if (follow_symlinks)
1095 return 0;
1096
1097 argument_unavailable_error(function_name, "follow_symlinks");
1098 return 1;
1099}
1100
1101static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001102path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1103{
Steve Dowercc16be82016-09-08 10:35:16 -07001104 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1105#ifndef MS_WINDOWS
1106 && !path->narrow
1107#endif
1108 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 PyErr_Format(PyExc_ValueError,
1110 "%s: can't specify dir_fd without matching path",
1111 function_name);
1112 return 1;
1113 }
1114 return 0;
1115}
1116
1117static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001118dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1119{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001120 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1121 PyErr_Format(PyExc_ValueError,
1122 "%s: can't specify both dir_fd and fd",
1123 function_name);
1124 return 1;
1125 }
1126 return 0;
1127}
1128
1129static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001130fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1131 int follow_symlinks)
1132{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001133 if ((fd > 0) && (!follow_symlinks)) {
1134 PyErr_Format(PyExc_ValueError,
1135 "%s: cannot use fd and follow_symlinks together",
1136 function_name);
1137 return 1;
1138 }
1139 return 0;
1140}
1141
1142static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001143dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1144 int follow_symlinks)
1145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1147 PyErr_Format(PyExc_ValueError,
1148 "%s: cannot use dir_fd and follow_symlinks together",
1149 function_name);
1150 return 1;
1151 }
1152 return 0;
1153}
1154
Larry Hastings2f936352014-08-05 14:04:04 +10001155#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001156 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001157#else
Larry Hastings2f936352014-08-05 14:04:04 +10001158 typedef off_t Py_off_t;
1159#endif
1160
1161static int
1162Py_off_t_converter(PyObject *arg, void *addr)
1163{
1164#ifdef HAVE_LARGEFILE_SUPPORT
1165 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1166#else
1167 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001168#endif
1169 if (PyErr_Occurred())
1170 return 0;
1171 return 1;
1172}
Larry Hastings2f936352014-08-05 14:04:04 +10001173
1174static PyObject *
1175PyLong_FromPy_off_t(Py_off_t offset)
1176{
1177#ifdef HAVE_LARGEFILE_SUPPORT
1178 return PyLong_FromLongLong(offset);
1179#else
1180 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001181#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001182}
1183
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001184#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001185
1186static int
Brian Curtind25aef52011-06-13 15:16:04 -05001187win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001188{
Martin Panter70214ad2016-08-04 02:38:59 +00001189 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1190 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001191 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001192
1193 if (0 == DeviceIoControl(
1194 reparse_point_handle,
1195 FSCTL_GET_REPARSE_POINT,
1196 NULL, 0, /* in buffer */
1197 target_buffer, sizeof(target_buffer),
1198 &n_bytes_returned,
1199 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001200 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001201
1202 if (reparse_tag)
1203 *reparse_tag = rdb->ReparseTag;
1204
Brian Curtind25aef52011-06-13 15:16:04 -05001205 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001206}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001207
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001208#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001209
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001210/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001211#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001212/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001213** environ directly, we must obtain it with _NSGetEnviron(). See also
1214** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001215*/
1216#include <crt_externs.h>
1217static char **environ;
1218#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001220#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221
Barry Warsaw53699e91996-12-10 23:23:01 +00001222static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001223convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001224{
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001226#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001228#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001229 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001230#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001231
Victor Stinner8c62be82010-05-06 00:08:46 +00001232 d = PyDict_New();
1233 if (d == NULL)
1234 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001235#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001236 if (environ == NULL)
1237 environ = *_NSGetEnviron();
1238#endif
1239#ifdef MS_WINDOWS
1240 /* _wenviron must be initialized in this way if the program is started
1241 through main() instead of wmain(). */
1242 _wgetenv(L"");
1243 if (_wenviron == NULL)
1244 return d;
1245 /* This part ignores errors */
1246 for (e = _wenviron; *e != NULL; e++) {
1247 PyObject *k;
1248 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001249 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001250 if (p == NULL)
1251 continue;
1252 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1253 if (k == NULL) {
1254 PyErr_Clear();
1255 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001256 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001257 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1258 if (v == NULL) {
1259 PyErr_Clear();
1260 Py_DECREF(k);
1261 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001262 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001263 if (PyDict_GetItem(d, k) == NULL) {
1264 if (PyDict_SetItem(d, k, v) != 0)
1265 PyErr_Clear();
1266 }
1267 Py_DECREF(k);
1268 Py_DECREF(v);
1269 }
1270#else
1271 if (environ == NULL)
1272 return d;
1273 /* This part ignores errors */
1274 for (e = environ; *e != NULL; e++) {
1275 PyObject *k;
1276 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001277 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 if (p == NULL)
1279 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001280 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001281 if (k == NULL) {
1282 PyErr_Clear();
1283 continue;
1284 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001285 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001286 if (v == NULL) {
1287 PyErr_Clear();
1288 Py_DECREF(k);
1289 continue;
1290 }
1291 if (PyDict_GetItem(d, k) == NULL) {
1292 if (PyDict_SetItem(d, k, v) != 0)
1293 PyErr_Clear();
1294 }
1295 Py_DECREF(k);
1296 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001297 }
1298#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300}
1301
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302/* Set a POSIX-specific error from errno, and return NULL */
1303
Barry Warsawd58d7641998-07-23 16:14:40 +00001304static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001305posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001306{
Victor Stinner8c62be82010-05-06 00:08:46 +00001307 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308}
Mark Hammondef8b6542001-05-13 08:04:26 +00001309
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001310#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001311static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001312win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001313{
Victor Stinner8c62be82010-05-06 00:08:46 +00001314 /* XXX We should pass the function name along in the future.
1315 (winreg.c also wants to pass the function name.)
1316 This would however require an additional param to the
1317 Windows error object, which is non-trivial.
1318 */
1319 errno = GetLastError();
1320 if (filename)
1321 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1322 else
1323 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001324}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001325
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001326static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001327win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001328{
1329 /* XXX - see win32_error for comments on 'function' */
1330 errno = GetLastError();
1331 if (filename)
1332 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001333 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001334 errno,
1335 filename);
1336 else
1337 return PyErr_SetFromWindowsErr(errno);
1338}
1339
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001340#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341
Larry Hastings9cf065c2012-06-22 16:30:09 -07001342static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001343path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001344{
1345#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001346 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1347 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001348#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001349 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001350#endif
1351}
1352
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001353static PyObject *
1354path_object_error2(PyObject *path, PyObject *path2)
1355{
1356#ifdef MS_WINDOWS
1357 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1358 PyExc_OSError, 0, path, path2);
1359#else
1360 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1361#endif
1362}
1363
1364static PyObject *
1365path_error(path_t *path)
1366{
1367 return path_object_error(path->object);
1368}
Larry Hastings31826802013-10-19 00:09:25 -07001369
Larry Hastingsb0827312014-02-09 22:05:19 -08001370static PyObject *
1371path_error2(path_t *path, path_t *path2)
1372{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001373 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001374}
1375
1376
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377/* POSIX generic methods */
1378
Larry Hastings2f936352014-08-05 14:04:04 +10001379static int
1380fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001381{
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001383 int *pointer = (int *)p;
1384 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001386 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001387 *pointer = fd;
1388 return 1;
1389}
1390
1391static PyObject *
1392posix_fildes_fd(int fd, int (*func)(int))
1393{
1394 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001395 int async_err = 0;
1396
1397 do {
1398 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001399 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001400 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001401 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001402 Py_END_ALLOW_THREADS
1403 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1404 if (res != 0)
1405 return (!async_err) ? posix_error() : NULL;
1406 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001407}
Guido van Rossum21142a01999-01-08 21:05:37 +00001408
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001409
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001410#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411/* This is a reimplementation of the C library's chdir function,
1412 but one that produces Win32 errors instead of DOS error codes.
1413 chdir is essentially a wrapper around SetCurrentDirectory; however,
1414 it also needs to set "magic" environment variables indicating
1415 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001416static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417win32_wchdir(LPCWSTR path)
1418{
Victor Stinnered537822015-12-13 21:40:26 +01001419 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 int result;
1421 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001422
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 if(!SetCurrentDirectoryW(path))
1424 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001425 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 if (!result)
1427 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001428 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001429 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 if (!new_path) {
1431 SetLastError(ERROR_OUTOFMEMORY);
1432 return FALSE;
1433 }
1434 result = GetCurrentDirectoryW(result, new_path);
1435 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001436 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 return FALSE;
1438 }
1439 }
1440 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1441 wcsncmp(new_path, L"//", 2) == 0)
1442 /* UNC path, nothing to do. */
1443 return TRUE;
1444 env[1] = new_path[0];
1445 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001446 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001447 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001449}
1450#endif
1451
Martin v. Löwis14694662006-02-03 12:54:16 +00001452#ifdef MS_WINDOWS
1453/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1454 - time stamps are restricted to second resolution
1455 - file modification times suffer from forth-and-back conversions between
1456 UTC and local time
1457 Therefore, we implement our own stat, based on the Win32 API directly.
1458*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001459#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001460#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001461
Victor Stinner6036e442015-03-08 01:58:04 +01001462static void
Steve Dowercc16be82016-09-08 10:35:16 -07001463find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1464 BY_HANDLE_FILE_INFORMATION *info,
1465 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001466{
1467 memset(info, 0, sizeof(*info));
1468 info->dwFileAttributes = pFileData->dwFileAttributes;
1469 info->ftCreationTime = pFileData->ftCreationTime;
1470 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1471 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1472 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1473 info->nFileSizeLow = pFileData->nFileSizeLow;
1474/* info->nNumberOfLinks = 1; */
1475 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1476 *reparse_tag = pFileData->dwReserved0;
1477 else
1478 *reparse_tag = 0;
1479}
1480
Guido van Rossumd8faa362007-04-27 19:54:29 +00001481static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001482attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001483{
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 HANDLE hFindFile;
1485 WIN32_FIND_DATAW FileData;
1486 hFindFile = FindFirstFileW(pszFile, &FileData);
1487 if (hFindFile == INVALID_HANDLE_VALUE)
1488 return FALSE;
1489 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001490 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001492}
1493
Brian Curtind25aef52011-06-13 15:16:04 -05001494static BOOL
1495get_target_path(HANDLE hdl, wchar_t **target_path)
1496{
1497 int buf_size, result_length;
1498 wchar_t *buf;
1499
1500 /* We have a good handle to the target, use it to determine
1501 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001502 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1503 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001504 if(!buf_size)
1505 return FALSE;
1506
Victor Stinnerc36674a2016-03-16 14:30:16 +01001507 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001508 if (!buf) {
1509 SetLastError(ERROR_OUTOFMEMORY);
1510 return FALSE;
1511 }
1512
Steve Dower2ea51c92015-03-20 21:49:12 -07001513 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001514 buf, buf_size, VOLUME_NAME_DOS);
1515
1516 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001517 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001518 return FALSE;
1519 }
1520
1521 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001522 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001523 return FALSE;
1524 }
1525
1526 buf[result_length] = 0;
1527
1528 *target_path = buf;
1529 return TRUE;
1530}
1531
1532static int
Steve Dowercc16be82016-09-08 10:35:16 -07001533win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001534 BOOL traverse)
1535{
Victor Stinner26de69d2011-06-17 15:15:38 +02001536 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001537 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001539 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001540 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001541 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001542
Steve Dowercc16be82016-09-08 10:35:16 -07001543 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001544 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001545 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001546 0, /* share mode */
1547 NULL, /* security attributes */
1548 OPEN_EXISTING,
1549 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001550 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1551 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001552 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001553 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1554 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001555 NULL);
1556
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001557 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558 /* Either the target doesn't exist, or we don't have access to
1559 get a handle to it. If the former, we need to return an error.
1560 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001561 DWORD lastError = GetLastError();
1562 if (lastError != ERROR_ACCESS_DENIED &&
1563 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001564 return -1;
1565 /* Could not get attributes on open file. Fall back to
1566 reading the directory. */
1567 if (!attributes_from_dir(path, &info, &reparse_tag))
1568 /* Very strange. This should not fail now */
1569 return -1;
1570 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1571 if (traverse) {
1572 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001573 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001574 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001576 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001577 } else {
1578 if (!GetFileInformationByHandle(hFile, &info)) {
1579 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001580 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001581 }
1582 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001583 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1584 return -1;
1585
1586 /* Close the outer open file handle now that we're about to
1587 reopen it with different flags. */
1588 if (!CloseHandle(hFile))
1589 return -1;
1590
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001591 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001592 /* In order to call GetFinalPathNameByHandle we need to open
1593 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001594 hFile2 = CreateFileW(
1595 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1596 NULL, OPEN_EXISTING,
1597 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1598 NULL);
1599 if (hFile2 == INVALID_HANDLE_VALUE)
1600 return -1;
1601
1602 if (!get_target_path(hFile2, &target_path))
1603 return -1;
1604
Steve Dowercc16be82016-09-08 10:35:16 -07001605 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001606 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 return code;
1608 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001609 } else
1610 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001611 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001612 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001613
1614 /* Set S_IEXEC if it is an .exe, .bat, ... */
1615 dot = wcsrchr(path, '.');
1616 if (dot) {
1617 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1618 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1619 result->st_mode |= 0111;
1620 }
1621 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622}
1623
1624static int
Steve Dowercc16be82016-09-08 10:35:16 -07001625win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 /* Protocol violation: we explicitly clear errno, instead of
1628 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001629 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 errno = 0;
1631 return code;
1632}
Brian Curtind25aef52011-06-13 15:16:04 -05001633/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001634
1635 In Posix, stat automatically traverses symlinks and returns the stat
1636 structure for the target. In Windows, the equivalent GetFileAttributes by
1637 default does not traverse symlinks and instead returns attributes for
1638 the symlink.
1639
1640 Therefore, win32_lstat will get the attributes traditionally, and
1641 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001642 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001643
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001644static int
Steve Dowercc16be82016-09-08 10:35:16 -07001645win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001646{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001647 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001648}
1649
Victor Stinner8c62be82010-05-06 00:08:46 +00001650static int
Steve Dowercc16be82016-09-08 10:35:16 -07001651win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001652{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001653 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001654}
1655
Martin v. Löwis14694662006-02-03 12:54:16 +00001656#endif /* MS_WINDOWS */
1657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001659"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001660This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001661 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001662or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1663\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001664Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1665or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001666\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001667See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001668
1669static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001670 {"st_mode", "protection bits"},
1671 {"st_ino", "inode"},
1672 {"st_dev", "device"},
1673 {"st_nlink", "number of hard links"},
1674 {"st_uid", "user ID of owner"},
1675 {"st_gid", "group ID of owner"},
1676 {"st_size", "total size, in bytes"},
1677 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1678 {NULL, "integer time of last access"},
1679 {NULL, "integer time of last modification"},
1680 {NULL, "integer time of last change"},
1681 {"st_atime", "time of last access"},
1682 {"st_mtime", "time of last modification"},
1683 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001684 {"st_atime_ns", "time of last access in nanoseconds"},
1685 {"st_mtime_ns", "time of last modification in nanoseconds"},
1686 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001687#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001689#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001690#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001691 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001692#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001693#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001694 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001695#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001696#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001697 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001698#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001699#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001700 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001701#endif
1702#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001703 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001704#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001705#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1706 {"st_file_attributes", "Windows file attribute bits"},
1707#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001708 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001709};
1710
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001711#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001712#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001713#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001714#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001715#endif
1716
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001717#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001718#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1719#else
1720#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1721#endif
1722
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001723#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001724#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1725#else
1726#define ST_RDEV_IDX ST_BLOCKS_IDX
1727#endif
1728
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001729#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1730#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1731#else
1732#define ST_FLAGS_IDX ST_RDEV_IDX
1733#endif
1734
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001735#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001736#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001737#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001738#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001739#endif
1740
1741#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1742#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1743#else
1744#define ST_BIRTHTIME_IDX ST_GEN_IDX
1745#endif
1746
Zachary Ware63f277b2014-06-19 09:46:37 -05001747#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1748#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1749#else
1750#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1751#endif
1752
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001753static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 "stat_result", /* name */
1755 stat_result__doc__, /* doc */
1756 stat_result_fields,
1757 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001758};
1759
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001760PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001761"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1762This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001763 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001764or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001766See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001767
1768static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001769 {"f_bsize", },
1770 {"f_frsize", },
1771 {"f_blocks", },
1772 {"f_bfree", },
1773 {"f_bavail", },
1774 {"f_files", },
1775 {"f_ffree", },
1776 {"f_favail", },
1777 {"f_flag", },
1778 {"f_namemax",},
1779 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780};
1781
1782static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001783 "statvfs_result", /* name */
1784 statvfs_result__doc__, /* doc */
1785 statvfs_result_fields,
1786 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001787};
1788
Ross Lagerwall7807c352011-03-17 20:20:30 +02001789#if defined(HAVE_WAITID) && !defined(__APPLE__)
1790PyDoc_STRVAR(waitid_result__doc__,
1791"waitid_result: Result from waitid.\n\n\
1792This object may be accessed either as a tuple of\n\
1793 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1794or via the attributes si_pid, si_uid, and so on.\n\
1795\n\
1796See os.waitid for more information.");
1797
1798static PyStructSequence_Field waitid_result_fields[] = {
1799 {"si_pid", },
1800 {"si_uid", },
1801 {"si_signo", },
1802 {"si_status", },
1803 {"si_code", },
1804 {0}
1805};
1806
1807static PyStructSequence_Desc waitid_result_desc = {
1808 "waitid_result", /* name */
1809 waitid_result__doc__, /* doc */
1810 waitid_result_fields,
1811 5
1812};
1813static PyTypeObject WaitidResultType;
1814#endif
1815
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001816static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001817static PyTypeObject StatResultType;
1818static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001819#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001820static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001821#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001822static newfunc structseq_new;
1823
1824static PyObject *
1825statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1826{
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 PyStructSequence *result;
1828 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001829
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 result = (PyStructSequence*)structseq_new(type, args, kwds);
1831 if (!result)
1832 return NULL;
1833 /* If we have been initialized from a tuple,
1834 st_?time might be set to None. Initialize it
1835 from the int slots. */
1836 for (i = 7; i <= 9; i++) {
1837 if (result->ob_item[i+3] == Py_None) {
1838 Py_DECREF(Py_None);
1839 Py_INCREF(result->ob_item[i]);
1840 result->ob_item[i+3] = result->ob_item[i];
1841 }
1842 }
1843 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001844}
1845
1846
1847
1848/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001849static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001850
1851PyDoc_STRVAR(stat_float_times__doc__,
1852"stat_float_times([newval]) -> oldval\n\n\
1853Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001854\n\
1855If value is True, future calls to stat() return floats; if it is False,\n\
1856future calls return ints.\n\
1857If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001858
Larry Hastings2f936352014-08-05 14:04:04 +10001859/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001860static PyObject*
1861stat_float_times(PyObject* self, PyObject *args)
1862{
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 int newval = -1;
1864 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1865 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001866 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1867 "stat_float_times() is deprecated",
1868 1))
1869 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001870 if (newval == -1)
1871 /* Return old value */
1872 return PyBool_FromLong(_stat_float_times);
1873 _stat_float_times = newval;
1874 Py_INCREF(Py_None);
1875 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001876}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001877
Larry Hastings6fe20b32012-04-19 15:07:49 -07001878static PyObject *billion = NULL;
1879
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001880static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001881fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001882{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001883 PyObject *s = _PyLong_FromTime_t(sec);
1884 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1885 PyObject *s_in_ns = NULL;
1886 PyObject *ns_total = NULL;
1887 PyObject *float_s = NULL;
1888
1889 if (!(s && ns_fractional))
1890 goto exit;
1891
1892 s_in_ns = PyNumber_Multiply(s, billion);
1893 if (!s_in_ns)
1894 goto exit;
1895
1896 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1897 if (!ns_total)
1898 goto exit;
1899
Victor Stinner4195b5c2012-02-08 23:03:19 +01001900 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001901 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1902 if (!float_s)
1903 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001904 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001905 else {
1906 float_s = s;
1907 Py_INCREF(float_s);
1908 }
1909
1910 PyStructSequence_SET_ITEM(v, index, s);
1911 PyStructSequence_SET_ITEM(v, index+3, float_s);
1912 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1913 s = NULL;
1914 float_s = NULL;
1915 ns_total = NULL;
1916exit:
1917 Py_XDECREF(s);
1918 Py_XDECREF(ns_fractional);
1919 Py_XDECREF(s_in_ns);
1920 Py_XDECREF(ns_total);
1921 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001922}
1923
Tim Peters5aa91602002-01-30 05:46:57 +00001924/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001925 (used by posix_stat() and posix_fstat()) */
1926static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001927_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001928{
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 unsigned long ansec, mnsec, cnsec;
1930 PyObject *v = PyStructSequence_New(&StatResultType);
1931 if (v == NULL)
1932 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001935#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001936 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001937 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001938#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001939 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001940#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001941#ifdef MS_WINDOWS
1942 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001943#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001944 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001945#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001947#if defined(MS_WINDOWS)
1948 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1949 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1950#else
1951 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1952 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1953#endif
Fred Drake699f3522000-06-29 21:12:41 +00001954#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001956 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001957#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001959#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001960
Martin v. Löwis14694662006-02-03 12:54:16 +00001961#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 ansec = st->st_atim.tv_nsec;
1963 mnsec = st->st_mtim.tv_nsec;
1964 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001965#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 ansec = st->st_atimespec.tv_nsec;
1967 mnsec = st->st_mtimespec.tv_nsec;
1968 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001969#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 ansec = st->st_atime_nsec;
1971 mnsec = st->st_mtime_nsec;
1972 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001973#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001976 fill_time(v, 7, st->st_atime, ansec);
1977 fill_time(v, 8, st->st_mtime, mnsec);
1978 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001979
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001980#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001981 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1982 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001984#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1986 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001987#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001988#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1990 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001991#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001992#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001993 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1994 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001995#endif
1996#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001998 PyObject *val;
1999 unsigned long bsec,bnsec;
2000 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002001#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002002 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002003#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002004 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002005#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002006 if (_stat_float_times) {
2007 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2008 } else {
2009 val = PyLong_FromLong((long)bsec);
2010 }
2011 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2012 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002014#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002015#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2017 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002018#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002019#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2020 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2021 PyLong_FromUnsignedLong(st->st_file_attributes));
2022#endif
Fred Drake699f3522000-06-29 21:12:41 +00002023
Victor Stinner8c62be82010-05-06 00:08:46 +00002024 if (PyErr_Occurred()) {
2025 Py_DECREF(v);
2026 return NULL;
2027 }
Fred Drake699f3522000-06-29 21:12:41 +00002028
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002030}
2031
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002032/* POSIX methods */
2033
Guido van Rossum94f6f721999-01-06 18:42:14 +00002034
2035static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002036posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002037 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002038{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002039 STRUCT_STAT st;
2040 int result;
2041
2042#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2043 if (follow_symlinks_specified(function_name, follow_symlinks))
2044 return NULL;
2045#endif
2046
2047 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2048 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2049 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2050 return NULL;
2051
2052 Py_BEGIN_ALLOW_THREADS
2053 if (path->fd != -1)
2054 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002055#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002056 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002057 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002058 else
Steve Dowercc16be82016-09-08 10:35:16 -07002059 result = win32_lstat(path->wide, &st);
2060#else
2061 else
2062#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002063 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2064 result = LSTAT(path->narrow, &st);
2065 else
Steve Dowercc16be82016-09-08 10:35:16 -07002066#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002067#ifdef HAVE_FSTATAT
2068 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2069 result = fstatat(dir_fd, path->narrow, &st,
2070 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2071 else
Steve Dowercc16be82016-09-08 10:35:16 -07002072#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002073 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002074#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075 Py_END_ALLOW_THREADS
2076
Victor Stinner292c8352012-10-30 02:17:38 +01002077 if (result != 0) {
2078 return path_error(path);
2079 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002080
2081 return _pystat_fromstructstat(&st);
2082}
2083
Larry Hastings2f936352014-08-05 14:04:04 +10002084/*[python input]
2085
2086for s in """
2087
2088FACCESSAT
2089FCHMODAT
2090FCHOWNAT
2091FSTATAT
2092LINKAT
2093MKDIRAT
2094MKFIFOAT
2095MKNODAT
2096OPENAT
2097READLINKAT
2098SYMLINKAT
2099UNLINKAT
2100
2101""".strip().split():
2102 s = s.strip()
2103 print("""
2104#ifdef HAVE_{s}
2105 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002106#else
Larry Hastings2f936352014-08-05 14:04:04 +10002107 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002108#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002109""".rstrip().format(s=s))
2110
2111for s in """
2112
2113FCHDIR
2114FCHMOD
2115FCHOWN
2116FDOPENDIR
2117FEXECVE
2118FPATHCONF
2119FSTATVFS
2120FTRUNCATE
2121
2122""".strip().split():
2123 s = s.strip()
2124 print("""
2125#ifdef HAVE_{s}
2126 #define PATH_HAVE_{s} 1
2127#else
2128 #define PATH_HAVE_{s} 0
2129#endif
2130
2131""".rstrip().format(s=s))
2132[python start generated code]*/
2133
2134#ifdef HAVE_FACCESSAT
2135 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2136#else
2137 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2138#endif
2139
2140#ifdef HAVE_FCHMODAT
2141 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2142#else
2143 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2144#endif
2145
2146#ifdef HAVE_FCHOWNAT
2147 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2148#else
2149 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2150#endif
2151
2152#ifdef HAVE_FSTATAT
2153 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2154#else
2155 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2156#endif
2157
2158#ifdef HAVE_LINKAT
2159 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2160#else
2161 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2162#endif
2163
2164#ifdef HAVE_MKDIRAT
2165 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2166#else
2167 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2168#endif
2169
2170#ifdef HAVE_MKFIFOAT
2171 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2172#else
2173 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2174#endif
2175
2176#ifdef HAVE_MKNODAT
2177 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2178#else
2179 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2180#endif
2181
2182#ifdef HAVE_OPENAT
2183 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2184#else
2185 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2186#endif
2187
2188#ifdef HAVE_READLINKAT
2189 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2190#else
2191 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2192#endif
2193
2194#ifdef HAVE_SYMLINKAT
2195 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_UNLINKAT
2201 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_FCHDIR
2207 #define PATH_HAVE_FCHDIR 1
2208#else
2209 #define PATH_HAVE_FCHDIR 0
2210#endif
2211
2212#ifdef HAVE_FCHMOD
2213 #define PATH_HAVE_FCHMOD 1
2214#else
2215 #define PATH_HAVE_FCHMOD 0
2216#endif
2217
2218#ifdef HAVE_FCHOWN
2219 #define PATH_HAVE_FCHOWN 1
2220#else
2221 #define PATH_HAVE_FCHOWN 0
2222#endif
2223
2224#ifdef HAVE_FDOPENDIR
2225 #define PATH_HAVE_FDOPENDIR 1
2226#else
2227 #define PATH_HAVE_FDOPENDIR 0
2228#endif
2229
2230#ifdef HAVE_FEXECVE
2231 #define PATH_HAVE_FEXECVE 1
2232#else
2233 #define PATH_HAVE_FEXECVE 0
2234#endif
2235
2236#ifdef HAVE_FPATHCONF
2237 #define PATH_HAVE_FPATHCONF 1
2238#else
2239 #define PATH_HAVE_FPATHCONF 0
2240#endif
2241
2242#ifdef HAVE_FSTATVFS
2243 #define PATH_HAVE_FSTATVFS 1
2244#else
2245 #define PATH_HAVE_FSTATVFS 0
2246#endif
2247
2248#ifdef HAVE_FTRUNCATE
2249 #define PATH_HAVE_FTRUNCATE 1
2250#else
2251 #define PATH_HAVE_FTRUNCATE 0
2252#endif
2253/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002254
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002255#ifdef MS_WINDOWS
2256 #undef PATH_HAVE_FTRUNCATE
2257 #define PATH_HAVE_FTRUNCATE 1
2258#endif
Larry Hastings31826802013-10-19 00:09:25 -07002259
Larry Hastings61272b72014-01-07 12:41:53 -08002260/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002261
2262class path_t_converter(CConverter):
2263
2264 type = "path_t"
2265 impl_by_reference = True
2266 parse_by_reference = True
2267
2268 converter = 'path_converter'
2269
2270 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002271 # right now path_t doesn't support default values.
2272 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002273 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002274 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002275
Larry Hastings2f936352014-08-05 14:04:04 +10002276 if self.c_default not in (None, 'Py_None'):
2277 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002278
2279 self.nullable = nullable
2280 self.allow_fd = allow_fd
2281
Larry Hastings7726ac92014-01-31 22:03:12 -08002282 def pre_render(self):
2283 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002284 if isinstance(value, str):
2285 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002286 return str(int(bool(value)))
2287
2288 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002289 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002290 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002291 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002292 strify(self.nullable),
2293 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002294 )
2295
2296 def cleanup(self):
2297 return "path_cleanup(&" + self.name + ");\n"
2298
2299
2300class dir_fd_converter(CConverter):
2301 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002302
Larry Hastings2f936352014-08-05 14:04:04 +10002303 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002304 if self.default in (unspecified, None):
2305 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002306 if isinstance(requires, str):
2307 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2308 else:
2309 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002310
Larry Hastings2f936352014-08-05 14:04:04 +10002311class fildes_converter(CConverter):
2312 type = 'int'
2313 converter = 'fildes_converter'
2314
2315class uid_t_converter(CConverter):
2316 type = "uid_t"
2317 converter = '_Py_Uid_Converter'
2318
2319class gid_t_converter(CConverter):
2320 type = "gid_t"
2321 converter = '_Py_Gid_Converter'
2322
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002323class dev_t_converter(CConverter):
2324 type = 'dev_t'
2325 converter = '_Py_Dev_Converter'
2326
2327class dev_t_return_converter(unsigned_long_return_converter):
2328 type = 'dev_t'
2329 conversion_fn = '_PyLong_FromDev'
2330 unsigned_cast = '(dev_t)'
2331
Larry Hastings2f936352014-08-05 14:04:04 +10002332class FSConverter_converter(CConverter):
2333 type = 'PyObject *'
2334 converter = 'PyUnicode_FSConverter'
2335 def converter_init(self):
2336 if self.default is not unspecified:
2337 fail("FSConverter_converter does not support default values")
2338 self.c_default = 'NULL'
2339
2340 def cleanup(self):
2341 return "Py_XDECREF(" + self.name + ");\n"
2342
2343class pid_t_converter(CConverter):
2344 type = 'pid_t'
2345 format_unit = '" _Py_PARSE_PID "'
2346
2347class idtype_t_converter(int_converter):
2348 type = 'idtype_t'
2349
2350class id_t_converter(CConverter):
2351 type = 'id_t'
2352 format_unit = '" _Py_PARSE_PID "'
2353
Benjamin Petersonca470632016-09-06 13:47:26 -07002354class intptr_t_converter(CConverter):
2355 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002356 format_unit = '" _Py_PARSE_INTPTR "'
2357
2358class Py_off_t_converter(CConverter):
2359 type = 'Py_off_t'
2360 converter = 'Py_off_t_converter'
2361
2362class Py_off_t_return_converter(long_return_converter):
2363 type = 'Py_off_t'
2364 conversion_fn = 'PyLong_FromPy_off_t'
2365
2366class path_confname_converter(CConverter):
2367 type="int"
2368 converter="conv_path_confname"
2369
2370class confstr_confname_converter(path_confname_converter):
2371 converter='conv_confstr_confname'
2372
2373class sysconf_confname_converter(path_confname_converter):
2374 converter="conv_sysconf_confname"
2375
2376class sched_param_converter(CConverter):
2377 type = 'struct sched_param'
2378 converter = 'convert_sched_param'
2379 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002380
Larry Hastings61272b72014-01-07 12:41:53 -08002381[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002382/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002383
Larry Hastings61272b72014-01-07 12:41:53 -08002384/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002385
Larry Hastings2a727912014-01-16 11:32:01 -08002386os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002387
2388 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002389 Path to be examined; can be string, bytes, path-like object or
2390 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002391
2392 *
2393
Larry Hastings2f936352014-08-05 14:04:04 +10002394 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002395 If not None, it should be a file descriptor open to a directory,
2396 and path should be a relative string; path will then be relative to
2397 that directory.
2398
2399 follow_symlinks: bool = True
2400 If False, and the last element of the path is a symbolic link,
2401 stat will examine the symbolic link itself instead of the file
2402 the link points to.
2403
2404Perform a stat system call on the given path.
2405
2406dir_fd and follow_symlinks may not be implemented
2407 on your platform. If they are unavailable, using them will raise a
2408 NotImplementedError.
2409
2410It's an error to use dir_fd or follow_symlinks when specifying path as
2411 an open file descriptor.
2412
Larry Hastings61272b72014-01-07 12:41:53 -08002413[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002414
Larry Hastings31826802013-10-19 00:09:25 -07002415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002416os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002417/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002418{
2419 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2420}
2421
Larry Hastings2f936352014-08-05 14:04:04 +10002422
2423/*[clinic input]
2424os.lstat
2425
2426 path : path_t
2427
2428 *
2429
2430 dir_fd : dir_fd(requires='fstatat') = None
2431
2432Perform a stat system call on the given path, without following symbolic links.
2433
2434Like stat(), but do not follow symbolic links.
2435Equivalent to stat(path, follow_symlinks=False).
2436[clinic start generated code]*/
2437
Larry Hastings2f936352014-08-05 14:04:04 +10002438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002439os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2440/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002441{
2442 int follow_symlinks = 0;
2443 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2444}
Larry Hastings31826802013-10-19 00:09:25 -07002445
Larry Hastings2f936352014-08-05 14:04:04 +10002446
Larry Hastings61272b72014-01-07 12:41:53 -08002447/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002448os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002449
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002450 path: path_t
2451 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002452
2453 mode: int
2454 Operating-system mode bitfield. Can be F_OK to test existence,
2455 or the inclusive-OR of R_OK, W_OK, and X_OK.
2456
2457 *
2458
Larry Hastings2f936352014-08-05 14:04:04 +10002459 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002460 If not None, it should be a file descriptor open to a directory,
2461 and path should be relative; path will then be relative to that
2462 directory.
2463
2464 effective_ids: bool = False
2465 If True, access will use the effective uid/gid instead of
2466 the real uid/gid.
2467
2468 follow_symlinks: bool = True
2469 If False, and the last element of the path is a symbolic link,
2470 access will examine the symbolic link itself instead of the file
2471 the link points to.
2472
2473Use the real uid/gid to test for access to a path.
2474
2475{parameters}
2476dir_fd, effective_ids, and follow_symlinks may not be implemented
2477 on your platform. If they are unavailable, using them will raise a
2478 NotImplementedError.
2479
2480Note that most operations will use the effective uid/gid, therefore this
2481 routine can be used in a suid/sgid environment to test if the invoking user
2482 has the specified access to the path.
2483
Larry Hastings61272b72014-01-07 12:41:53 -08002484[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002485
Larry Hastings2f936352014-08-05 14:04:04 +10002486static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002487os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002488 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002489/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002490{
Larry Hastings2f936352014-08-05 14:04:04 +10002491 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002492
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002493#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002494 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002495#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002496 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002497#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002498
Larry Hastings9cf065c2012-06-22 16:30:09 -07002499#ifndef HAVE_FACCESSAT
2500 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002501 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002502
2503 if (effective_ids) {
2504 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002505 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002506 }
2507#endif
2508
2509#ifdef MS_WINDOWS
2510 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002511 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002512 Py_END_ALLOW_THREADS
2513
2514 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002515 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002516 * * we didn't get a -1, and
2517 * * write access wasn't requested,
2518 * * or the file isn't read-only,
2519 * * or it's a directory.
2520 * (Directories cannot be read-only on Windows.)
2521 */
Larry Hastings2f936352014-08-05 14:04:04 +10002522 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002523 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002524 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002525 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002526#else
2527
2528 Py_BEGIN_ALLOW_THREADS
2529#ifdef HAVE_FACCESSAT
2530 if ((dir_fd != DEFAULT_DIR_FD) ||
2531 effective_ids ||
2532 !follow_symlinks) {
2533 int flags = 0;
2534 if (!follow_symlinks)
2535 flags |= AT_SYMLINK_NOFOLLOW;
2536 if (effective_ids)
2537 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002538 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539 }
2540 else
2541#endif
Larry Hastings31826802013-10-19 00:09:25 -07002542 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002543 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002544 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002545#endif
2546
Larry Hastings9cf065c2012-06-22 16:30:09 -07002547 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002548}
2549
Guido van Rossumd371ff11999-01-25 16:12:23 +00002550#ifndef F_OK
2551#define F_OK 0
2552#endif
2553#ifndef R_OK
2554#define R_OK 4
2555#endif
2556#ifndef W_OK
2557#define W_OK 2
2558#endif
2559#ifndef X_OK
2560#define X_OK 1
2561#endif
2562
Larry Hastings31826802013-10-19 00:09:25 -07002563
Guido van Rossumd371ff11999-01-25 16:12:23 +00002564#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002565/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002566os.ttyname -> DecodeFSDefault
2567
2568 fd: int
2569 Integer file descriptor handle.
2570
2571 /
2572
2573Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002574[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002575
Larry Hastings31826802013-10-19 00:09:25 -07002576static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002577os_ttyname_impl(PyObject *module, int fd)
2578/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002579{
2580 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002581
Larry Hastings31826802013-10-19 00:09:25 -07002582 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002583 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002584 posix_error();
2585 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002586}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002587#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002588
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002589#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002590/*[clinic input]
2591os.ctermid
2592
2593Return the name of the controlling terminal for this process.
2594[clinic start generated code]*/
2595
Larry Hastings2f936352014-08-05 14:04:04 +10002596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002597os_ctermid_impl(PyObject *module)
2598/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002599{
Victor Stinner8c62be82010-05-06 00:08:46 +00002600 char *ret;
2601 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002602
Greg Wardb48bc172000-03-01 21:51:56 +00002603#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002604 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002605#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002606 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002607#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002608 if (ret == NULL)
2609 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002610 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002611}
Larry Hastings2f936352014-08-05 14:04:04 +10002612#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002613
Larry Hastings2f936352014-08-05 14:04:04 +10002614
2615/*[clinic input]
2616os.chdir
2617
2618 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2619
2620Change the current working directory to the specified path.
2621
2622path may always be specified as a string.
2623On some platforms, path may also be specified as an open file descriptor.
2624 If this functionality is unavailable, using it raises an exception.
2625[clinic start generated code]*/
2626
Larry Hastings2f936352014-08-05 14:04:04 +10002627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002628os_chdir_impl(PyObject *module, path_t *path)
2629/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002630{
2631 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632
2633 Py_BEGIN_ALLOW_THREADS
2634#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002635 /* on unix, success = 0, on windows, success = !0 */
2636 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002637#else
2638#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002639 if (path->fd != -1)
2640 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641 else
2642#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002643 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644#endif
2645 Py_END_ALLOW_THREADS
2646
2647 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002648 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002649 }
2650
Larry Hastings2f936352014-08-05 14:04:04 +10002651 Py_RETURN_NONE;
2652}
2653
2654
2655#ifdef HAVE_FCHDIR
2656/*[clinic input]
2657os.fchdir
2658
2659 fd: fildes
2660
2661Change to the directory of the given file descriptor.
2662
2663fd must be opened on a directory, not a file.
2664Equivalent to os.chdir(fd).
2665
2666[clinic start generated code]*/
2667
Fred Drake4d1e64b2002-04-15 19:40:07 +00002668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002669os_fchdir_impl(PyObject *module, int fd)
2670/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002671{
Larry Hastings2f936352014-08-05 14:04:04 +10002672 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002673}
2674#endif /* HAVE_FCHDIR */
2675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002676
Larry Hastings2f936352014-08-05 14:04:04 +10002677/*[clinic input]
2678os.chmod
2679
2680 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2681 Path to be modified. May always be specified as a str or bytes.
2682 On some platforms, path may also be specified as an open file descriptor.
2683 If this functionality is unavailable, using it raises an exception.
2684
2685 mode: int
2686 Operating-system mode bitfield.
2687
2688 *
2689
2690 dir_fd : dir_fd(requires='fchmodat') = None
2691 If not None, it should be a file descriptor open to a directory,
2692 and path should be relative; path will then be relative to that
2693 directory.
2694
2695 follow_symlinks: bool = True
2696 If False, and the last element of the path is a symbolic link,
2697 chmod will modify the symbolic link itself instead of the file
2698 the link points to.
2699
2700Change the access permissions of a file.
2701
2702It is an error to use dir_fd or follow_symlinks when specifying path as
2703 an open file descriptor.
2704dir_fd and follow_symlinks may not be implemented on your platform.
2705 If they are unavailable, using them will raise a NotImplementedError.
2706
2707[clinic start generated code]*/
2708
Larry Hastings2f936352014-08-05 14:04:04 +10002709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002710os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002711 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002712/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002713{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002714 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002715
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002716#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002717 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002718#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002719
Larry Hastings9cf065c2012-06-22 16:30:09 -07002720#ifdef HAVE_FCHMODAT
2721 int fchmodat_nofollow_unsupported = 0;
2722#endif
2723
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2725 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002726 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002727#endif
2728
2729#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002730 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002731 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002732 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733 result = 0;
2734 else {
2735 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002736 attr &= ~FILE_ATTRIBUTE_READONLY;
2737 else
2738 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002739 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740 }
2741 Py_END_ALLOW_THREADS
2742
2743 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002744 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002745 }
2746#else /* MS_WINDOWS */
2747 Py_BEGIN_ALLOW_THREADS
2748#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002749 if (path->fd != -1)
2750 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002751 else
2752#endif
2753#ifdef HAVE_LCHMOD
2754 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002755 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002756 else
2757#endif
2758#ifdef HAVE_FCHMODAT
2759 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2760 /*
2761 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2762 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002763 * and then says it isn't implemented yet.
2764 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002765 *
2766 * Once it is supported, os.chmod will automatically
2767 * support dir_fd and follow_symlinks=False. (Hopefully.)
2768 * Until then, we need to be careful what exception we raise.
2769 */
Larry Hastings2f936352014-08-05 14:04:04 +10002770 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2772 /*
2773 * But wait! We can't throw the exception without allowing threads,
2774 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2775 */
2776 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002777 result &&
2778 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2779 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002780 }
2781 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002782#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002783 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784 Py_END_ALLOW_THREADS
2785
2786 if (result) {
2787#ifdef HAVE_FCHMODAT
2788 if (fchmodat_nofollow_unsupported) {
2789 if (dir_fd != DEFAULT_DIR_FD)
2790 dir_fd_and_follow_symlinks_invalid("chmod",
2791 dir_fd, follow_symlinks);
2792 else
2793 follow_symlinks_specified("chmod", follow_symlinks);
2794 }
2795 else
2796#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002797 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798 }
2799#endif
2800
Larry Hastings2f936352014-08-05 14:04:04 +10002801 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002802}
2803
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804
Christian Heimes4e30a842007-11-30 22:12:06 +00002805#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002806/*[clinic input]
2807os.fchmod
2808
2809 fd: int
2810 mode: int
2811
2812Change the access permissions of the file given by file descriptor fd.
2813
2814Equivalent to os.chmod(fd, mode).
2815[clinic start generated code]*/
2816
Larry Hastings2f936352014-08-05 14:04:04 +10002817static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002818os_fchmod_impl(PyObject *module, int fd, int mode)
2819/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002820{
2821 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002822 int async_err = 0;
2823
2824 do {
2825 Py_BEGIN_ALLOW_THREADS
2826 res = fchmod(fd, mode);
2827 Py_END_ALLOW_THREADS
2828 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2829 if (res != 0)
2830 return (!async_err) ? posix_error() : NULL;
2831
Victor Stinner8c62be82010-05-06 00:08:46 +00002832 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002833}
2834#endif /* HAVE_FCHMOD */
2835
Larry Hastings2f936352014-08-05 14:04:04 +10002836
Christian Heimes4e30a842007-11-30 22:12:06 +00002837#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002838/*[clinic input]
2839os.lchmod
2840
2841 path: path_t
2842 mode: int
2843
2844Change the access permissions of a file, without following symbolic links.
2845
2846If path is a symlink, this affects the link itself rather than the target.
2847Equivalent to chmod(path, mode, follow_symlinks=False)."
2848[clinic start generated code]*/
2849
Larry Hastings2f936352014-08-05 14:04:04 +10002850static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002851os_lchmod_impl(PyObject *module, path_t *path, int mode)
2852/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002853{
Victor Stinner8c62be82010-05-06 00:08:46 +00002854 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002855 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002856 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002858 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002859 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002860 return NULL;
2861 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002862 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002863}
2864#endif /* HAVE_LCHMOD */
2865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002866
Thomas Wouterscf297e42007-02-23 15:07:44 +00002867#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002868/*[clinic input]
2869os.chflags
2870
2871 path: path_t
2872 flags: unsigned_long(bitwise=True)
2873 follow_symlinks: bool=True
2874
2875Set file flags.
2876
2877If follow_symlinks is False, and the last element of the path is a symbolic
2878 link, chflags will change flags on the symbolic link itself instead of the
2879 file the link points to.
2880follow_symlinks may not be implemented on your platform. If it is
2881unavailable, using it will raise a NotImplementedError.
2882
2883[clinic start generated code]*/
2884
Larry Hastings2f936352014-08-05 14:04:04 +10002885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002886os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002887 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002888/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002889{
2890 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002891
2892#ifndef HAVE_LCHFLAGS
2893 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002894 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895#endif
2896
Victor Stinner8c62be82010-05-06 00:08:46 +00002897 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002898#ifdef HAVE_LCHFLAGS
2899 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002900 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002901 else
2902#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002903 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002905
Larry Hastings2f936352014-08-05 14:04:04 +10002906 if (result)
2907 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002908
Larry Hastings2f936352014-08-05 14:04:04 +10002909 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002910}
2911#endif /* HAVE_CHFLAGS */
2912
Larry Hastings2f936352014-08-05 14:04:04 +10002913
Thomas Wouterscf297e42007-02-23 15:07:44 +00002914#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002915/*[clinic input]
2916os.lchflags
2917
2918 path: path_t
2919 flags: unsigned_long(bitwise=True)
2920
2921Set file flags.
2922
2923This function will not follow symbolic links.
2924Equivalent to chflags(path, flags, follow_symlinks=False).
2925[clinic start generated code]*/
2926
Larry Hastings2f936352014-08-05 14:04:04 +10002927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002928os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2929/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002930{
Victor Stinner8c62be82010-05-06 00:08:46 +00002931 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002932 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002933 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002935 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002936 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002937 }
Victor Stinner292c8352012-10-30 02:17:38 +01002938 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002939}
2940#endif /* HAVE_LCHFLAGS */
2941
Larry Hastings2f936352014-08-05 14:04:04 +10002942
Martin v. Löwis244edc82001-10-04 22:44:26 +00002943#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002944/*[clinic input]
2945os.chroot
2946 path: path_t
2947
2948Change root directory to path.
2949
2950[clinic start generated code]*/
2951
Larry Hastings2f936352014-08-05 14:04:04 +10002952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002953os_chroot_impl(PyObject *module, path_t *path)
2954/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002955{
2956 int res;
2957 Py_BEGIN_ALLOW_THREADS
2958 res = chroot(path->narrow);
2959 Py_END_ALLOW_THREADS
2960 if (res < 0)
2961 return path_error(path);
2962 Py_RETURN_NONE;
2963}
2964#endif /* HAVE_CHROOT */
2965
Martin v. Löwis244edc82001-10-04 22:44:26 +00002966
Guido van Rossum21142a01999-01-08 21:05:37 +00002967#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002968/*[clinic input]
2969os.fsync
2970
2971 fd: fildes
2972
2973Force write of fd to disk.
2974[clinic start generated code]*/
2975
Larry Hastings2f936352014-08-05 14:04:04 +10002976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002977os_fsync_impl(PyObject *module, int fd)
2978/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002979{
2980 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002981}
2982#endif /* HAVE_FSYNC */
2983
Larry Hastings2f936352014-08-05 14:04:04 +10002984
Ross Lagerwall7807c352011-03-17 20:20:30 +02002985#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002986/*[clinic input]
2987os.sync
2988
2989Force write of everything to disk.
2990[clinic start generated code]*/
2991
Larry Hastings2f936352014-08-05 14:04:04 +10002992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002993os_sync_impl(PyObject *module)
2994/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002995{
2996 Py_BEGIN_ALLOW_THREADS
2997 sync();
2998 Py_END_ALLOW_THREADS
2999 Py_RETURN_NONE;
3000}
Larry Hastings2f936352014-08-05 14:04:04 +10003001#endif /* HAVE_SYNC */
3002
Ross Lagerwall7807c352011-03-17 20:20:30 +02003003
Guido van Rossum21142a01999-01-08 21:05:37 +00003004#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003005#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003006extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3007#endif
3008
Larry Hastings2f936352014-08-05 14:04:04 +10003009/*[clinic input]
3010os.fdatasync
3011
3012 fd: fildes
3013
3014Force write of fd to disk without forcing update of metadata.
3015[clinic start generated code]*/
3016
Larry Hastings2f936352014-08-05 14:04:04 +10003017static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003018os_fdatasync_impl(PyObject *module, int fd)
3019/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003020{
3021 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003022}
3023#endif /* HAVE_FDATASYNC */
3024
3025
Fredrik Lundh10723342000-07-10 16:38:09 +00003026#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003027/*[clinic input]
3028os.chown
3029
3030 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3031 Path to be examined; can be string, bytes, or open-file-descriptor int.
3032
3033 uid: uid_t
3034
3035 gid: gid_t
3036
3037 *
3038
3039 dir_fd : dir_fd(requires='fchownat') = None
3040 If not None, it should be a file descriptor open to a directory,
3041 and path should be relative; path will then be relative to that
3042 directory.
3043
3044 follow_symlinks: bool = True
3045 If False, and the last element of the path is a symbolic link,
3046 stat will examine the symbolic link itself instead of the file
3047 the link points to.
3048
3049Change the owner and group id of path to the numeric uid and gid.\
3050
3051path may always be specified as a string.
3052On some platforms, path may also be specified as an open file descriptor.
3053 If this functionality is unavailable, using it raises an exception.
3054If dir_fd is not None, it should be a file descriptor open to a directory,
3055 and path should be relative; path will then be relative to that directory.
3056If follow_symlinks is False, and the last element of the path is a symbolic
3057 link, chown will modify the symbolic link itself instead of the file the
3058 link points to.
3059It is an error to use dir_fd or follow_symlinks when specifying path as
3060 an open file descriptor.
3061dir_fd and follow_symlinks may not be implemented on your platform.
3062 If they are unavailable, using them will raise a NotImplementedError.
3063
3064[clinic start generated code]*/
3065
Larry Hastings2f936352014-08-05 14:04:04 +10003066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003067os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003068 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003069/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003070{
3071 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072
3073#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3074 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003075 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003077 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3078 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3079 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003080
3081#ifdef __APPLE__
3082 /*
3083 * This is for Mac OS X 10.3, which doesn't have lchown.
3084 * (But we still have an lchown symbol because of weak-linking.)
3085 * It doesn't have fchownat either. So there's no possibility
3086 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003087 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088 if ((!follow_symlinks) && (lchown == NULL)) {
3089 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003090 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003091 }
3092#endif
3093
Victor Stinner8c62be82010-05-06 00:08:46 +00003094 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003096 if (path->fd != -1)
3097 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003098 else
3099#endif
3100#ifdef HAVE_LCHOWN
3101 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003102 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003103 else
3104#endif
3105#ifdef HAVE_FCHOWNAT
3106 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003107 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3109 else
3110#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003111 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003112 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003113
Larry Hastings2f936352014-08-05 14:04:04 +10003114 if (result)
3115 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003116
Larry Hastings2f936352014-08-05 14:04:04 +10003117 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003118}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003119#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003120
Larry Hastings2f936352014-08-05 14:04:04 +10003121
Christian Heimes4e30a842007-11-30 22:12:06 +00003122#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003123/*[clinic input]
3124os.fchown
3125
3126 fd: int
3127 uid: uid_t
3128 gid: gid_t
3129
3130Change the owner and group id of the file specified by file descriptor.
3131
3132Equivalent to os.chown(fd, uid, gid).
3133
3134[clinic start generated code]*/
3135
Larry Hastings2f936352014-08-05 14:04:04 +10003136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003137os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3138/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003139{
Victor Stinner8c62be82010-05-06 00:08:46 +00003140 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003141 int async_err = 0;
3142
3143 do {
3144 Py_BEGIN_ALLOW_THREADS
3145 res = fchown(fd, uid, gid);
3146 Py_END_ALLOW_THREADS
3147 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3148 if (res != 0)
3149 return (!async_err) ? posix_error() : NULL;
3150
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003152}
3153#endif /* HAVE_FCHOWN */
3154
Larry Hastings2f936352014-08-05 14:04:04 +10003155
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003156#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003157/*[clinic input]
3158os.lchown
3159
3160 path : path_t
3161 uid: uid_t
3162 gid: gid_t
3163
3164Change the owner and group id of path to the numeric uid and gid.
3165
3166This function will not follow symbolic links.
3167Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3168[clinic start generated code]*/
3169
Larry Hastings2f936352014-08-05 14:04:04 +10003170static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003171os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3172/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003173{
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003176 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003178 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003179 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003180 }
Larry Hastings2f936352014-08-05 14:04:04 +10003181 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003182}
3183#endif /* HAVE_LCHOWN */
3184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003185
Barry Warsaw53699e91996-12-10 23:23:01 +00003186static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003187posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003188{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003189 char *buf, *tmpbuf;
3190 char *cwd;
3191 const size_t chunk = 1024;
3192 size_t buflen = 0;
3193 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003194
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003195#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003196 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003197 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 wchar_t *wbuf2 = wbuf;
3199 PyObject *resobj;
3200 DWORD len;
3201 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003202 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003203 /* If the buffer is large enough, len does not include the
3204 terminating \0. If the buffer is too small, len includes
3205 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003206 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003207 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 if (wbuf2)
3209 len = GetCurrentDirectoryW(len, wbuf2);
3210 }
3211 Py_END_ALLOW_THREADS
3212 if (!wbuf2) {
3213 PyErr_NoMemory();
3214 return NULL;
3215 }
3216 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003217 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003218 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003219 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003220 }
3221 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003222 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003223 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 return resobj;
3225 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003226
3227 if (win32_warn_bytes_api())
3228 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003229#endif
3230
Victor Stinner4403d7d2015-04-25 00:16:10 +02003231 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003233 do {
3234 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003235#ifdef MS_WINDOWS
3236 if (buflen > INT_MAX) {
3237 PyErr_NoMemory();
3238 break;
3239 }
3240#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003241 tmpbuf = PyMem_RawRealloc(buf, buflen);
3242 if (tmpbuf == NULL)
3243 break;
3244
3245 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003246#ifdef MS_WINDOWS
3247 cwd = getcwd(buf, (int)buflen);
3248#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003249 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003250#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003251 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003253
3254 if (cwd == NULL) {
3255 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003257 }
3258
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003260 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3261 else
3262 obj = PyUnicode_DecodeFSDefault(buf);
3263 PyMem_RawFree(buf);
3264
3265 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003266}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003267
Larry Hastings2f936352014-08-05 14:04:04 +10003268
3269/*[clinic input]
3270os.getcwd
3271
3272Return a unicode string representing the current working directory.
3273[clinic start generated code]*/
3274
Larry Hastings2f936352014-08-05 14:04:04 +10003275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003276os_getcwd_impl(PyObject *module)
3277/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003278{
3279 return posix_getcwd(0);
3280}
3281
Larry Hastings2f936352014-08-05 14:04:04 +10003282
3283/*[clinic input]
3284os.getcwdb
3285
3286Return a bytes string representing the current working directory.
3287[clinic start generated code]*/
3288
Larry Hastings2f936352014-08-05 14:04:04 +10003289static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003290os_getcwdb_impl(PyObject *module)
3291/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003292{
3293 return posix_getcwd(1);
3294}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003295
Larry Hastings2f936352014-08-05 14:04:04 +10003296
Larry Hastings9cf065c2012-06-22 16:30:09 -07003297#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3298#define HAVE_LINK 1
3299#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003300
Guido van Rossumb6775db1994-08-01 11:34:53 +00003301#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003302/*[clinic input]
3303
3304os.link
3305
3306 src : path_t
3307 dst : path_t
3308 *
3309 src_dir_fd : dir_fd = None
3310 dst_dir_fd : dir_fd = None
3311 follow_symlinks: bool = True
3312
3313Create a hard link to a file.
3314
3315If either src_dir_fd or dst_dir_fd is not None, it should be a file
3316 descriptor open to a directory, and the respective path string (src or dst)
3317 should be relative; the path will then be relative to that directory.
3318If follow_symlinks is False, and the last element of src is a symbolic
3319 link, link will create a link to the symbolic link itself instead of the
3320 file the link points to.
3321src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3322 platform. If they are unavailable, using them will raise a
3323 NotImplementedError.
3324[clinic start generated code]*/
3325
Larry Hastings2f936352014-08-05 14:04:04 +10003326static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003327os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003328 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003329/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003330{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003331#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003332 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333#else
3334 int result;
3335#endif
3336
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337#ifndef HAVE_LINKAT
3338 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3339 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003340 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003341 }
3342#endif
3343
Steve Dowercc16be82016-09-08 10:35:16 -07003344#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003345 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003346 PyErr_SetString(PyExc_NotImplementedError,
3347 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003348 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349 }
Steve Dowercc16be82016-09-08 10:35:16 -07003350#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003351
Brian Curtin1b9df392010-11-24 20:24:31 +00003352#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003353 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003354 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003355 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003356
Larry Hastings2f936352014-08-05 14:04:04 +10003357 if (!result)
3358 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003359#else
3360 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003361#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3363 (dst_dir_fd != DEFAULT_DIR_FD) ||
3364 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003365 result = linkat(src_dir_fd, src->narrow,
3366 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003367 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3368 else
Steve Dowercc16be82016-09-08 10:35:16 -07003369#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003370 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003372
Larry Hastings2f936352014-08-05 14:04:04 +10003373 if (result)
3374 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003375#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376
Larry Hastings2f936352014-08-05 14:04:04 +10003377 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003378}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379#endif
3380
Brian Curtin1b9df392010-11-24 20:24:31 +00003381
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003382#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003383static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003384_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003385{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 PyObject *v;
3387 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3388 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003389 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003390 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003391 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003393
Steve Dowercc16be82016-09-08 10:35:16 -07003394 WIN32_FIND_DATAW wFileData;
3395 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003396
Steve Dowercc16be82016-09-08 10:35:16 -07003397 if (!path->wide) { /* Default arg: "." */
3398 po_wchars = L".";
3399 len = 1;
3400 } else {
3401 po_wchars = path->wide;
3402 len = wcslen(path->wide);
3403 }
3404 /* The +5 is so we can append "\\*.*\0" */
3405 wnamebuf = PyMem_New(wchar_t, len + 5);
3406 if (!wnamebuf) {
3407 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 }
Steve Dowercc16be82016-09-08 10:35:16 -07003410 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003412 wchar_t wch = wnamebuf[len-1];
3413 if (wch != SEP && wch != ALTSEP && wch != L':')
3414 wnamebuf[len++] = SEP;
3415 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 }
Steve Dowercc16be82016-09-08 10:35:16 -07003417 if ((list = PyList_New(0)) == NULL) {
3418 goto exit;
3419 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003420 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003421 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003422 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 if (hFindFile == INVALID_HANDLE_VALUE) {
3424 int error = GetLastError();
3425 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 goto exit;
3427 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003428 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 }
3431 do {
3432 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003433 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3434 wcscmp(wFileData.cFileName, L"..") != 0) {
3435 v = PyUnicode_FromWideChar(wFileData.cFileName,
3436 wcslen(wFileData.cFileName));
3437 if (path->narrow && v) {
3438 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3439 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 Py_DECREF(list);
3442 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003443 break;
3444 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447 Py_DECREF(list);
3448 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003449 break;
3450 }
3451 Py_DECREF(v);
3452 }
3453 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003454 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 Py_END_ALLOW_THREADS
3456 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3457 it got to the end of the directory. */
3458 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003459 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003460 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 }
3463 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003464
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465exit:
3466 if (hFindFile != INVALID_HANDLE_VALUE) {
3467 if (FindClose(hFindFile) == FALSE) {
3468 if (list != NULL) {
3469 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003470 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 }
3472 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003473 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003474 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003475
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003477} /* end of _listdir_windows_no_opendir */
3478
3479#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3480
3481static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003482_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003483{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003484 PyObject *v;
3485 DIR *dirp = NULL;
3486 struct dirent *ep;
3487 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003488#ifdef HAVE_FDOPENDIR
3489 int fd = -1;
3490#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003491
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003494 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003496 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003497 if (fd == -1)
3498 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499
Larry Hastingsfdaea062012-06-25 04:42:23 -07003500 return_str = 1;
3501
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_BEGIN_ALLOW_THREADS
3503 dirp = fdopendir(fd);
3504 Py_END_ALLOW_THREADS
3505 }
3506 else
3507#endif
3508 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003509 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003510 if (path->narrow) {
3511 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003512 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003513 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003514 }
3515 else {
3516 name = ".";
3517 return_str = 1;
3518 }
3519
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_BEGIN_ALLOW_THREADS
3521 dirp = opendir(name);
3522 Py_END_ALLOW_THREADS
3523 }
3524
3525 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003526 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003527#ifdef HAVE_FDOPENDIR
3528 if (fd != -1) {
3529 Py_BEGIN_ALLOW_THREADS
3530 close(fd);
3531 Py_END_ALLOW_THREADS
3532 }
3533#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 goto exit;
3535 }
3536 if ((list = PyList_New(0)) == NULL) {
3537 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 }
3539 for (;;) {
3540 errno = 0;
3541 Py_BEGIN_ALLOW_THREADS
3542 ep = readdir(dirp);
3543 Py_END_ALLOW_THREADS
3544 if (ep == NULL) {
3545 if (errno == 0) {
3546 break;
3547 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003549 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 }
3552 }
3553 if (ep->d_name[0] == '.' &&
3554 (NAMLEN(ep) == 1 ||
3555 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3556 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003557 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003558 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3559 else
3560 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 break;
3564 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003566 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 break;
3569 }
3570 Py_DECREF(v);
3571 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003572
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573exit:
3574 if (dirp != NULL) {
3575 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003576#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 if (fd > -1)
3578 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003579#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 closedir(dirp);
3581 Py_END_ALLOW_THREADS
3582 }
3583
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003585} /* end of _posix_listdir */
3586#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003587
Larry Hastings2f936352014-08-05 14:04:04 +10003588
3589/*[clinic input]
3590os.listdir
3591
3592 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3593
3594Return a list containing the names of the files in the directory.
3595
3596path can be specified as either str or bytes. If path is bytes,
3597 the filenames returned will also be bytes; in all other circumstances
3598 the filenames returned will be str.
3599If path is None, uses the path='.'.
3600On some platforms, path may also be specified as an open file descriptor;\
3601 the file descriptor must refer to a directory.
3602 If this functionality is unavailable, using it raises NotImplementedError.
3603
3604The list is in arbitrary order. It does not include the special
3605entries '.' and '..' even if they are present in the directory.
3606
3607
3608[clinic start generated code]*/
3609
Larry Hastings2f936352014-08-05 14:04:04 +10003610static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003611os_listdir_impl(PyObject *module, path_t *path)
3612/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003613{
3614#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3615 return _listdir_windows_no_opendir(path, NULL);
3616#else
3617 return _posix_listdir(path, NULL);
3618#endif
3619}
3620
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003621#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003622/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003623/*[clinic input]
3624os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003625
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003626 path: path_t
3627 /
3628
3629[clinic start generated code]*/
3630
3631static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003632os__getfullpathname_impl(PyObject *module, path_t *path)
3633/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003634{
Steve Dowercc16be82016-09-08 10:35:16 -07003635 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3636 wchar_t *wtemp;
3637 DWORD result;
3638 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003639
Steve Dowercc16be82016-09-08 10:35:16 -07003640 result = GetFullPathNameW(path->wide,
3641 Py_ARRAY_LENGTH(woutbuf),
3642 woutbuf, &wtemp);
3643 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3644 woutbufp = PyMem_New(wchar_t, result);
3645 if (!woutbufp)
3646 return PyErr_NoMemory();
3647 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 }
Steve Dowercc16be82016-09-08 10:35:16 -07003649 if (result) {
3650 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3651 if (path->narrow)
3652 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3653 } else
3654 v = win32_error_object("GetFullPathNameW", path->object);
3655 if (woutbufp != woutbuf)
3656 PyMem_Free(woutbufp);
3657 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003658}
Brian Curtind40e6f72010-07-08 21:39:08 +00003659
Brian Curtind25aef52011-06-13 15:16:04 -05003660
Larry Hastings2f936352014-08-05 14:04:04 +10003661/*[clinic input]
3662os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003663
Larry Hastings2f936352014-08-05 14:04:04 +10003664 path: unicode
3665 /
3666
3667A helper function for samepath on windows.
3668[clinic start generated code]*/
3669
Larry Hastings2f936352014-08-05 14:04:04 +10003670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003671os__getfinalpathname_impl(PyObject *module, PyObject *path)
3672/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003673{
3674 HANDLE hFile;
3675 int buf_size;
3676 wchar_t *target_path;
3677 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003678 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003679 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003680
Larry Hastings2f936352014-08-05 14:04:04 +10003681 path_wchar = PyUnicode_AsUnicode(path);
3682 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003683 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003684
Brian Curtind40e6f72010-07-08 21:39:08 +00003685 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003686 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003687 0, /* desired access */
3688 0, /* share mode */
3689 NULL, /* security attributes */
3690 OPEN_EXISTING,
3691 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3692 FILE_FLAG_BACKUP_SEMANTICS,
3693 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003694
Victor Stinnereb5657a2011-09-30 01:44:27 +02003695 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003696 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003697
3698 /* We have a good handle to the target, use it to determine the
3699 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003700 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003701
3702 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003703 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003704
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003705 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003706 if(!target_path)
3707 return PyErr_NoMemory();
3708
Steve Dower2ea51c92015-03-20 21:49:12 -07003709 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3710 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003711 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003712 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003713
3714 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003715 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003716
3717 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003718 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003719 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003720 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003721}
Brian Curtin62857742010-09-06 17:07:27 +00003722
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003723/*[clinic input]
3724os._isdir
3725
3726 path: path_t
3727 /
3728
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003729Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003730[clinic start generated code]*/
3731
Brian Curtin9c669cc2011-06-08 18:17:18 -05003732static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003733os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003734/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003735{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003736 DWORD attributes;
3737
Steve Dowerb22a6772016-07-17 20:49:38 -07003738 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003739 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003740 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003741
Brian Curtin9c669cc2011-06-08 18:17:18 -05003742 if (attributes == INVALID_FILE_ATTRIBUTES)
3743 Py_RETURN_FALSE;
3744
Brian Curtin9c669cc2011-06-08 18:17:18 -05003745 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3746 Py_RETURN_TRUE;
3747 else
3748 Py_RETURN_FALSE;
3749}
Tim Golden6b528062013-08-01 12:44:00 +01003750
Tim Golden6b528062013-08-01 12:44:00 +01003751
Larry Hastings2f936352014-08-05 14:04:04 +10003752/*[clinic input]
3753os._getvolumepathname
3754
3755 path: unicode
3756
3757A helper function for ismount on Win32.
3758[clinic start generated code]*/
3759
Larry Hastings2f936352014-08-05 14:04:04 +10003760static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003761os__getvolumepathname_impl(PyObject *module, PyObject *path)
3762/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003763{
3764 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003765 const wchar_t *path_wchar;
3766 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003767 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003768 BOOL ret;
3769
Larry Hastings2f936352014-08-05 14:04:04 +10003770 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3771 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003772 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003773 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003774
3775 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003776 buflen = Py_MAX(buflen, MAX_PATH);
3777
3778 if (buflen > DWORD_MAX) {
3779 PyErr_SetString(PyExc_OverflowError, "path too long");
3780 return NULL;
3781 }
3782
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003783 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003784 if (mountpath == NULL)
3785 return PyErr_NoMemory();
3786
3787 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003788 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003789 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003790 Py_END_ALLOW_THREADS
3791
3792 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003793 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003794 goto exit;
3795 }
3796 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3797
3798exit:
3799 PyMem_Free(mountpath);
3800 return result;
3801}
Tim Golden6b528062013-08-01 12:44:00 +01003802
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003803#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003804
Larry Hastings2f936352014-08-05 14:04:04 +10003805
3806/*[clinic input]
3807os.mkdir
3808
3809 path : path_t
3810
3811 mode: int = 0o777
3812
3813 *
3814
3815 dir_fd : dir_fd(requires='mkdirat') = None
3816
3817# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3818
3819Create a directory.
3820
3821If dir_fd is not None, it should be a file descriptor open to a directory,
3822 and path should be relative; path will then be relative to that directory.
3823dir_fd may not be implemented on your platform.
3824 If it is unavailable, using it will raise a NotImplementedError.
3825
3826The mode argument is ignored on Windows.
3827[clinic start generated code]*/
3828
Larry Hastings2f936352014-08-05 14:04:04 +10003829static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003830os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3831/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003832{
3833 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003834
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003835#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003836 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003837 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003839
Larry Hastings2f936352014-08-05 14:04:04 +10003840 if (!result)
3841 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003842#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003843 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003844#if HAVE_MKDIRAT
3845 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003846 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003847 else
3848#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003849#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003850 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003851#else
Larry Hastings2f936352014-08-05 14:04:04 +10003852 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003853#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003854 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003855 if (result < 0)
3856 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003857#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003858 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003859}
3860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003861
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003862/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3863#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003864#include <sys/resource.h>
3865#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003866
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003867
3868#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003869/*[clinic input]
3870os.nice
3871
3872 increment: int
3873 /
3874
3875Add increment to the priority of process and return the new priority.
3876[clinic start generated code]*/
3877
Larry Hastings2f936352014-08-05 14:04:04 +10003878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003879os_nice_impl(PyObject *module, int increment)
3880/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003881{
3882 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003883
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 /* There are two flavours of 'nice': one that returns the new
3885 priority (as required by almost all standards out there) and the
3886 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3887 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003888
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 If we are of the nice family that returns the new priority, we
3890 need to clear errno before the call, and check if errno is filled
3891 before calling posix_error() on a returnvalue of -1, because the
3892 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003893
Victor Stinner8c62be82010-05-06 00:08:46 +00003894 errno = 0;
3895 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003896#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 if (value == 0)
3898 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003899#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 if (value == -1 && errno != 0)
3901 /* either nice() or getpriority() returned an error */
3902 return posix_error();
3903 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003904}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003905#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003906
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003907
3908#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003909/*[clinic input]
3910os.getpriority
3911
3912 which: int
3913 who: int
3914
3915Return program scheduling priority.
3916[clinic start generated code]*/
3917
Larry Hastings2f936352014-08-05 14:04:04 +10003918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003919os_getpriority_impl(PyObject *module, int which, int who)
3920/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003921{
3922 int retval;
3923
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003924 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003925 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003926 if (errno != 0)
3927 return posix_error();
3928 return PyLong_FromLong((long)retval);
3929}
3930#endif /* HAVE_GETPRIORITY */
3931
3932
3933#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003934/*[clinic input]
3935os.setpriority
3936
3937 which: int
3938 who: int
3939 priority: int
3940
3941Set program scheduling priority.
3942[clinic start generated code]*/
3943
Larry Hastings2f936352014-08-05 14:04:04 +10003944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003945os_setpriority_impl(PyObject *module, int which, int who, int priority)
3946/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003947{
3948 int retval;
3949
3950 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003951 if (retval == -1)
3952 return posix_error();
3953 Py_RETURN_NONE;
3954}
3955#endif /* HAVE_SETPRIORITY */
3956
3957
Barry Warsaw53699e91996-12-10 23:23:01 +00003958static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003959internal_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 +00003960{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003961 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003962 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003963
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003964#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003966 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003967#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003968 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003969#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970
Larry Hastings9cf065c2012-06-22 16:30:09 -07003971 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3972 (dst_dir_fd != DEFAULT_DIR_FD);
3973#ifndef HAVE_RENAMEAT
3974 if (dir_fd_specified) {
3975 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003976 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003977 }
3978#endif
3979
Larry Hastings9cf065c2012-06-22 16:30:09 -07003980#ifdef MS_WINDOWS
3981 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003982 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003983 Py_END_ALLOW_THREADS
3984
Larry Hastings2f936352014-08-05 14:04:04 +10003985 if (!result)
3986 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987
3988#else
Steve Dowercc16be82016-09-08 10:35:16 -07003989 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3990 PyErr_Format(PyExc_ValueError,
3991 "%s: src and dst must be the same type", function_name);
3992 return NULL;
3993 }
3994
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995 Py_BEGIN_ALLOW_THREADS
3996#ifdef HAVE_RENAMEAT
3997 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10003998 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999 else
4000#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004001 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002 Py_END_ALLOW_THREADS
4003
Larry Hastings2f936352014-08-05 14:04:04 +10004004 if (result)
4005 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004007 Py_RETURN_NONE;
4008}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004009
Larry Hastings2f936352014-08-05 14:04:04 +10004010
4011/*[clinic input]
4012os.rename
4013
4014 src : path_t
4015 dst : path_t
4016 *
4017 src_dir_fd : dir_fd = None
4018 dst_dir_fd : dir_fd = None
4019
4020Rename a file or directory.
4021
4022If either src_dir_fd or dst_dir_fd is not None, it should be a file
4023 descriptor open to a directory, and the respective path string (src or dst)
4024 should be relative; the path will then be relative to that directory.
4025src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4026 If they are unavailable, using them will raise a NotImplementedError.
4027[clinic start generated code]*/
4028
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004029static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004030os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004031 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004032/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004033{
Larry Hastings2f936352014-08-05 14:04:04 +10004034 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004035}
4036
Larry Hastings2f936352014-08-05 14:04:04 +10004037
4038/*[clinic input]
4039os.replace = os.rename
4040
4041Rename a file or directory, overwriting the destination.
4042
4043If either src_dir_fd or dst_dir_fd is not None, it should be a file
4044 descriptor open to a directory, and the respective path string (src or dst)
4045 should be relative; the path will then be relative to that directory.
4046src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4047 If they are unavailable, using them will raise a NotImplementedError."
4048[clinic start generated code]*/
4049
Larry Hastings2f936352014-08-05 14:04:04 +10004050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004051os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4052 int dst_dir_fd)
4053/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004054{
4055 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4056}
4057
4058
4059/*[clinic input]
4060os.rmdir
4061
4062 path: path_t
4063 *
4064 dir_fd: dir_fd(requires='unlinkat') = None
4065
4066Remove a directory.
4067
4068If dir_fd is not None, it should be a file descriptor open to a directory,
4069 and path should be relative; path will then be relative to that directory.
4070dir_fd may not be implemented on your platform.
4071 If it is unavailable, using it will raise a NotImplementedError.
4072[clinic start generated code]*/
4073
Larry Hastings2f936352014-08-05 14:04:04 +10004074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004075os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4076/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004077{
4078 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004079
4080 Py_BEGIN_ALLOW_THREADS
4081#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004082 /* Windows, success=1, UNIX, success=0 */
4083 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004084#else
4085#ifdef HAVE_UNLINKAT
4086 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004087 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004088 else
4089#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004090 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004091#endif
4092 Py_END_ALLOW_THREADS
4093
Larry Hastings2f936352014-08-05 14:04:04 +10004094 if (result)
4095 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004096
Larry Hastings2f936352014-08-05 14:04:04 +10004097 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004098}
4099
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004100
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004101#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004102#ifdef MS_WINDOWS
4103/*[clinic input]
4104os.system -> long
4105
4106 command: Py_UNICODE
4107
4108Execute the command in a subshell.
4109[clinic start generated code]*/
4110
Larry Hastings2f936352014-08-05 14:04:04 +10004111static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004112os_system_impl(PyObject *module, Py_UNICODE *command)
4113/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004114{
4115 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004116 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004117 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004118 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004119 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004120 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004121 return result;
4122}
4123#else /* MS_WINDOWS */
4124/*[clinic input]
4125os.system -> long
4126
4127 command: FSConverter
4128
4129Execute the command in a subshell.
4130[clinic start generated code]*/
4131
Larry Hastings2f936352014-08-05 14:04:04 +10004132static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004133os_system_impl(PyObject *module, PyObject *command)
4134/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004135{
4136 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004137 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004138 Py_BEGIN_ALLOW_THREADS
4139 result = system(bytes);
4140 Py_END_ALLOW_THREADS
4141 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004142}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004143#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004144#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004146
Larry Hastings2f936352014-08-05 14:04:04 +10004147/*[clinic input]
4148os.umask
4149
4150 mask: int
4151 /
4152
4153Set the current numeric umask and return the previous umask.
4154[clinic start generated code]*/
4155
Larry Hastings2f936352014-08-05 14:04:04 +10004156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004157os_umask_impl(PyObject *module, int mask)
4158/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004159{
4160 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004161 if (i < 0)
4162 return posix_error();
4163 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004164}
4165
Brian Curtind40e6f72010-07-08 21:39:08 +00004166#ifdef MS_WINDOWS
4167
4168/* override the default DeleteFileW behavior so that directory
4169symlinks can be removed with this function, the same as with
4170Unix symlinks */
4171BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4172{
4173 WIN32_FILE_ATTRIBUTE_DATA info;
4174 WIN32_FIND_DATAW find_data;
4175 HANDLE find_data_handle;
4176 int is_directory = 0;
4177 int is_link = 0;
4178
4179 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4180 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004181
Brian Curtind40e6f72010-07-08 21:39:08 +00004182 /* Get WIN32_FIND_DATA structure for the path to determine if
4183 it is a symlink */
4184 if(is_directory &&
4185 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4186 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4187
4188 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004189 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4190 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4191 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4192 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004193 FindClose(find_data_handle);
4194 }
4195 }
4196 }
4197
4198 if (is_directory && is_link)
4199 return RemoveDirectoryW(lpFileName);
4200
4201 return DeleteFileW(lpFileName);
4202}
4203#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004204
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004205
Larry Hastings2f936352014-08-05 14:04:04 +10004206/*[clinic input]
4207os.unlink
4208
4209 path: path_t
4210 *
4211 dir_fd: dir_fd(requires='unlinkat')=None
4212
4213Remove a file (same as remove()).
4214
4215If dir_fd is not None, it should be a file descriptor open to a directory,
4216 and path should be relative; path will then be relative to that directory.
4217dir_fd may not be implemented on your platform.
4218 If it is unavailable, using it will raise a NotImplementedError.
4219
4220[clinic start generated code]*/
4221
Larry Hastings2f936352014-08-05 14:04:04 +10004222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004223os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4224/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004225{
4226 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004227
4228 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004229 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004230#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004231 /* Windows, success=1, UNIX, success=0 */
4232 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004234#ifdef HAVE_UNLINKAT
4235 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004236 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004237 else
4238#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004239 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004240#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004241 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004242 Py_END_ALLOW_THREADS
4243
Larry Hastings2f936352014-08-05 14:04:04 +10004244 if (result)
4245 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004246
Larry Hastings2f936352014-08-05 14:04:04 +10004247 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004248}
4249
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250
Larry Hastings2f936352014-08-05 14:04:04 +10004251/*[clinic input]
4252os.remove = os.unlink
4253
4254Remove a file (same as unlink()).
4255
4256If dir_fd is not None, it should be a file descriptor open to a directory,
4257 and path should be relative; path will then be relative to that directory.
4258dir_fd may not be implemented on your platform.
4259 If it is unavailable, using it will raise a NotImplementedError.
4260[clinic start generated code]*/
4261
Larry Hastings2f936352014-08-05 14:04:04 +10004262static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004263os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4264/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004265{
4266 return os_unlink_impl(module, path, dir_fd);
4267}
4268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004269
Larry Hastings605a62d2012-06-24 04:33:36 -07004270static PyStructSequence_Field uname_result_fields[] = {
4271 {"sysname", "operating system name"},
4272 {"nodename", "name of machine on network (implementation-defined)"},
4273 {"release", "operating system release"},
4274 {"version", "operating system version"},
4275 {"machine", "hardware identifier"},
4276 {NULL}
4277};
4278
4279PyDoc_STRVAR(uname_result__doc__,
4280"uname_result: Result from os.uname().\n\n\
4281This object may be accessed either as a tuple of\n\
4282 (sysname, nodename, release, version, machine),\n\
4283or via the attributes sysname, nodename, release, version, and machine.\n\
4284\n\
4285See os.uname for more information.");
4286
4287static PyStructSequence_Desc uname_result_desc = {
4288 "uname_result", /* name */
4289 uname_result__doc__, /* doc */
4290 uname_result_fields,
4291 5
4292};
4293
4294static PyTypeObject UnameResultType;
4295
4296
4297#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004298/*[clinic input]
4299os.uname
4300
4301Return an object identifying the current operating system.
4302
4303The object behaves like a named tuple with the following fields:
4304 (sysname, nodename, release, version, machine)
4305
4306[clinic start generated code]*/
4307
Larry Hastings2f936352014-08-05 14:04:04 +10004308static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004309os_uname_impl(PyObject *module)
4310/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004311{
Victor Stinner8c62be82010-05-06 00:08:46 +00004312 struct utsname u;
4313 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004314 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004315
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 Py_BEGIN_ALLOW_THREADS
4317 res = uname(&u);
4318 Py_END_ALLOW_THREADS
4319 if (res < 0)
4320 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004321
4322 value = PyStructSequence_New(&UnameResultType);
4323 if (value == NULL)
4324 return NULL;
4325
4326#define SET(i, field) \
4327 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004328 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004329 if (!o) { \
4330 Py_DECREF(value); \
4331 return NULL; \
4332 } \
4333 PyStructSequence_SET_ITEM(value, i, o); \
4334 } \
4335
4336 SET(0, u.sysname);
4337 SET(1, u.nodename);
4338 SET(2, u.release);
4339 SET(3, u.version);
4340 SET(4, u.machine);
4341
4342#undef SET
4343
4344 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004345}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004346#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004347
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004348
Larry Hastings9cf065c2012-06-22 16:30:09 -07004349
4350typedef struct {
4351 int now;
4352 time_t atime_s;
4353 long atime_ns;
4354 time_t mtime_s;
4355 long mtime_ns;
4356} utime_t;
4357
4358/*
Victor Stinner484df002014-10-09 13:52:31 +02004359 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360 * they also intentionally leak the declaration of a pointer named "time"
4361 */
4362#define UTIME_TO_TIMESPEC \
4363 struct timespec ts[2]; \
4364 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004365 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004366 time = NULL; \
4367 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004368 ts[0].tv_sec = ut->atime_s; \
4369 ts[0].tv_nsec = ut->atime_ns; \
4370 ts[1].tv_sec = ut->mtime_s; \
4371 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004372 time = ts; \
4373 } \
4374
4375#define UTIME_TO_TIMEVAL \
4376 struct timeval tv[2]; \
4377 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004378 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004379 time = NULL; \
4380 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004381 tv[0].tv_sec = ut->atime_s; \
4382 tv[0].tv_usec = ut->atime_ns / 1000; \
4383 tv[1].tv_sec = ut->mtime_s; \
4384 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004385 time = tv; \
4386 } \
4387
4388#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004389 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004390 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004391 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392 time = NULL; \
4393 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004394 u.actime = ut->atime_s; \
4395 u.modtime = ut->mtime_s; \
4396 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397 }
4398
4399#define UTIME_TO_TIME_T \
4400 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004401 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004402 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403 time = NULL; \
4404 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004405 timet[0] = ut->atime_s; \
4406 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004407 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004408 } \
4409
4410
Victor Stinner528a9ab2015-09-03 21:30:26 +02004411#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004412
4413static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004414utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004415{
4416#ifdef HAVE_UTIMENSAT
4417 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4418 UTIME_TO_TIMESPEC;
4419 return utimensat(dir_fd, path, time, flags);
4420#elif defined(HAVE_FUTIMESAT)
4421 UTIME_TO_TIMEVAL;
4422 /*
4423 * follow_symlinks will never be false here;
4424 * we only allow !follow_symlinks and dir_fd together
4425 * if we have utimensat()
4426 */
4427 assert(follow_symlinks);
4428 return futimesat(dir_fd, path, time);
4429#endif
4430}
4431
Larry Hastings2f936352014-08-05 14:04:04 +10004432 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4433#else
4434 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004435#endif
4436
Victor Stinner528a9ab2015-09-03 21:30:26 +02004437#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438
4439static int
Victor Stinner484df002014-10-09 13:52:31 +02004440utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004441{
4442#ifdef HAVE_FUTIMENS
4443 UTIME_TO_TIMESPEC;
4444 return futimens(fd, time);
4445#else
4446 UTIME_TO_TIMEVAL;
4447 return futimes(fd, time);
4448#endif
4449}
4450
Larry Hastings2f936352014-08-05 14:04:04 +10004451 #define PATH_UTIME_HAVE_FD 1
4452#else
4453 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004454#endif
4455
Victor Stinner5ebae872015-09-22 01:29:33 +02004456#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4457# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4458#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004459
Victor Stinner4552ced2015-09-21 22:37:15 +02004460#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004461
4462static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004463utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004464{
4465#ifdef HAVE_UTIMENSAT
4466 UTIME_TO_TIMESPEC;
4467 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4468#else
4469 UTIME_TO_TIMEVAL;
4470 return lutimes(path, time);
4471#endif
4472}
4473
4474#endif
4475
4476#ifndef MS_WINDOWS
4477
4478static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004479utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480{
4481#ifdef HAVE_UTIMENSAT
4482 UTIME_TO_TIMESPEC;
4483 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4484#elif defined(HAVE_UTIMES)
4485 UTIME_TO_TIMEVAL;
4486 return utimes(path, time);
4487#elif defined(HAVE_UTIME_H)
4488 UTIME_TO_UTIMBUF;
4489 return utime(path, time);
4490#else
4491 UTIME_TO_TIME_T;
4492 return utime(path, time);
4493#endif
4494}
4495
4496#endif
4497
Larry Hastings76ad59b2012-05-03 00:30:07 -07004498static int
4499split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4500{
4501 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004502 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004503 divmod = PyNumber_Divmod(py_long, billion);
4504 if (!divmod)
4505 goto exit;
4506 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4507 if ((*s == -1) && PyErr_Occurred())
4508 goto exit;
4509 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004510 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004511 goto exit;
4512
4513 result = 1;
4514exit:
4515 Py_XDECREF(divmod);
4516 return result;
4517}
4518
Larry Hastings2f936352014-08-05 14:04:04 +10004519
4520/*[clinic input]
4521os.utime
4522
4523 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4524 times: object = NULL
4525 *
4526 ns: object = NULL
4527 dir_fd: dir_fd(requires='futimensat') = None
4528 follow_symlinks: bool=True
4529
Martin Panter0ff89092015-09-09 01:56:53 +00004530# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004531
4532Set the access and modified time of path.
4533
4534path may always be specified as a string.
4535On some platforms, path may also be specified as an open file descriptor.
4536 If this functionality is unavailable, using it raises an exception.
4537
4538If times is not None, it must be a tuple (atime, mtime);
4539 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004540If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004541 atime_ns and mtime_ns should be expressed as integer nanoseconds
4542 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004543If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004544Specifying tuples for both times and ns is an error.
4545
4546If dir_fd is not None, it should be a file descriptor open to a directory,
4547 and path should be relative; path will then be relative to that directory.
4548If follow_symlinks is False, and the last element of the path is a symbolic
4549 link, utime will modify the symbolic link itself instead of the file the
4550 link points to.
4551It is an error to use dir_fd or follow_symlinks when specifying path
4552 as an open file descriptor.
4553dir_fd and follow_symlinks may not be available on your platform.
4554 If they are unavailable, using them will raise a NotImplementedError.
4555
4556[clinic start generated code]*/
4557
Larry Hastings2f936352014-08-05 14:04:04 +10004558static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004559os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4560 int dir_fd, int follow_symlinks)
4561/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004562{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563#ifdef MS_WINDOWS
4564 HANDLE hFile;
4565 FILETIME atime, mtime;
4566#else
4567 int result;
4568#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004569
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004571 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004572
Christian Heimesb3c87242013-08-01 00:08:16 +02004573 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004574
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 if (times && (times != Py_None) && ns) {
4576 PyErr_SetString(PyExc_ValueError,
4577 "utime: you may specify either 'times'"
4578 " or 'ns' but not both");
4579 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004580 }
4581
4582 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004583 time_t a_sec, m_sec;
4584 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004585 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586 PyErr_SetString(PyExc_TypeError,
4587 "utime: 'times' must be either"
4588 " a tuple of two ints or None");
4589 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004592 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004593 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004594 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004595 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004596 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004597 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004598 utime.atime_s = a_sec;
4599 utime.atime_ns = a_nsec;
4600 utime.mtime_s = m_sec;
4601 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004602 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004604 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605 PyErr_SetString(PyExc_TypeError,
4606 "utime: 'ns' must be a tuple of two ints");
4607 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004608 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004609 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004610 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004612 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613 &utime.mtime_s, &utime.mtime_ns)) {
4614 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004615 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004616 }
4617 else {
4618 /* times and ns are both None/unspecified. use "now". */
4619 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004620 }
4621
Victor Stinner4552ced2015-09-21 22:37:15 +02004622#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004623 if (follow_symlinks_specified("utime", follow_symlinks))
4624 goto exit;
4625#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004626
Larry Hastings2f936352014-08-05 14:04:04 +10004627 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4628 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4629 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004631
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632#if !defined(HAVE_UTIMENSAT)
4633 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004634 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004635 "utime: cannot use dir_fd and follow_symlinks "
4636 "together on this platform");
4637 goto exit;
4638 }
4639#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004640
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004641#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004643 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4644 NULL, OPEN_EXISTING,
4645 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 Py_END_ALLOW_THREADS
4647 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004648 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004650 }
4651
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004653 GetSystemTimeAsFileTime(&mtime);
4654 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004655 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004656 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004657 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4658 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004659 }
4660 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4661 /* Avoid putting the file name into the error here,
4662 as that may confuse the user into believing that
4663 something is wrong with the file, when it also
4664 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004665 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004666 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004667 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004668#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004670
Victor Stinner4552ced2015-09-21 22:37:15 +02004671#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004672 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004673 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004675#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004676
Victor Stinner528a9ab2015-09-03 21:30:26 +02004677#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004679 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680 else
4681#endif
4682
Victor Stinner528a9ab2015-09-03 21:30:26 +02004683#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004684 if (path->fd != -1)
4685 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 else
4687#endif
4688
Larry Hastings2f936352014-08-05 14:04:04 +10004689 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690
4691 Py_END_ALLOW_THREADS
4692
4693 if (result < 0) {
4694 /* see previous comment about not putting filename in error here */
4695 return_value = posix_error();
4696 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004697 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004698
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004699#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700
4701 Py_INCREF(Py_None);
4702 return_value = Py_None;
4703
4704exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004705#ifdef MS_WINDOWS
4706 if (hFile != INVALID_HANDLE_VALUE)
4707 CloseHandle(hFile);
4708#endif
4709 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004710}
4711
Guido van Rossum3b066191991-06-04 19:40:25 +00004712/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004713
Larry Hastings2f936352014-08-05 14:04:04 +10004714
4715/*[clinic input]
4716os._exit
4717
4718 status: int
4719
4720Exit to the system with specified status, without normal exit processing.
4721[clinic start generated code]*/
4722
Larry Hastings2f936352014-08-05 14:04:04 +10004723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004724os__exit_impl(PyObject *module, int status)
4725/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004726{
4727 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004728 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004729}
4730
Steve Dowercc16be82016-09-08 10:35:16 -07004731#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4732#define EXECV_CHAR wchar_t
4733#else
4734#define EXECV_CHAR char
4735#endif
4736
Martin v. Löwis114619e2002-10-07 06:44:21 +00004737#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4738static void
Steve Dowercc16be82016-09-08 10:35:16 -07004739free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004740{
Victor Stinner8c62be82010-05-06 00:08:46 +00004741 Py_ssize_t i;
4742 for (i = 0; i < count; i++)
4743 PyMem_Free(array[i]);
4744 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004745}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004746
Berker Peksag81816462016-09-15 20:19:47 +03004747static int
4748fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004749{
Victor Stinner8c62be82010-05-06 00:08:46 +00004750 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004751 PyObject *ub;
4752 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004753#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004754 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004755 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004756 *out = PyUnicode_AsWideCharString(ub, &size);
4757 if (*out)
4758 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004759#else
Berker Peksag81816462016-09-15 20:19:47 +03004760 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004761 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004762 size = PyBytes_GET_SIZE(ub);
4763 *out = PyMem_Malloc(size + 1);
4764 if (*out) {
4765 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4766 result = 1;
4767 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004768 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004769#endif
Berker Peksag81816462016-09-15 20:19:47 +03004770 Py_DECREF(ub);
4771 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004772}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004773#endif
4774
Ross Lagerwall7807c352011-03-17 20:20:30 +02004775#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004776static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004777parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4778{
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 Py_ssize_t i, pos, envc;
4780 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004781 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004782 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004783
Victor Stinner8c62be82010-05-06 00:08:46 +00004784 i = PyMapping_Size(env);
4785 if (i < 0)
4786 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004787 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 if (envlist == NULL) {
4789 PyErr_NoMemory();
4790 return NULL;
4791 }
4792 envc = 0;
4793 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004794 if (!keys)
4795 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004796 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004797 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 goto error;
4799 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4800 PyErr_Format(PyExc_TypeError,
4801 "env.keys() or env.values() is not a list");
4802 goto error;
4803 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004804
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 for (pos = 0; pos < i; pos++) {
4806 key = PyList_GetItem(keys, pos);
4807 val = PyList_GetItem(vals, pos);
4808 if (!key || !val)
4809 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004810
Berker Peksag81816462016-09-15 20:19:47 +03004811#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4812 if (!PyUnicode_FSDecoder(key, &key2))
4813 goto error;
4814 if (!PyUnicode_FSDecoder(val, &val2)) {
4815 Py_DECREF(key2);
4816 goto error;
4817 }
4818 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4819#else
4820 if (!PyUnicode_FSConverter(key, &key2))
4821 goto error;
4822 if (!PyUnicode_FSConverter(val, &val2)) {
4823 Py_DECREF(key2);
4824 goto error;
4825 }
4826 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4827 PyBytes_AS_STRING(val2));
4828#endif
4829 Py_DECREF(key2);
4830 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004831 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004833
4834 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4835 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 goto error;
4837 }
Berker Peksag81816462016-09-15 20:19:47 +03004838
Steve Dowercc16be82016-09-08 10:35:16 -07004839 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004840 }
4841 Py_DECREF(vals);
4842 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004843
Victor Stinner8c62be82010-05-06 00:08:46 +00004844 envlist[envc] = 0;
4845 *envc_ptr = envc;
4846 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004847
4848error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 Py_XDECREF(keys);
4850 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004851 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004853}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004854
Steve Dowercc16be82016-09-08 10:35:16 -07004855static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004856parse_arglist(PyObject* argv, Py_ssize_t *argc)
4857{
4858 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004859 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004860 if (argvlist == NULL) {
4861 PyErr_NoMemory();
4862 return NULL;
4863 }
4864 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004865 PyObject* item = PySequence_ITEM(argv, i);
4866 if (item == NULL)
4867 goto fail;
4868 if (!fsconvert_strdup(item, &argvlist[i])) {
4869 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004870 goto fail;
4871 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004872 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004873 }
4874 argvlist[*argc] = NULL;
4875 return argvlist;
4876fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004877 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004878 free_string_array(argvlist, *argc);
4879 return NULL;
4880}
Steve Dowercc16be82016-09-08 10:35:16 -07004881
Ross Lagerwall7807c352011-03-17 20:20:30 +02004882#endif
4883
Larry Hastings2f936352014-08-05 14:04:04 +10004884
Ross Lagerwall7807c352011-03-17 20:20:30 +02004885#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004886/*[clinic input]
4887os.execv
4888
Steve Dowercc16be82016-09-08 10:35:16 -07004889 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004890 Path of executable file.
4891 argv: object
4892 Tuple or list of strings.
4893 /
4894
4895Execute an executable path with arguments, replacing current process.
4896[clinic start generated code]*/
4897
Larry Hastings2f936352014-08-05 14:04:04 +10004898static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004899os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4900/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004901{
Steve Dowercc16be82016-09-08 10:35:16 -07004902 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004903 Py_ssize_t argc;
4904
4905 /* execv has two arguments: (path, argv), where
4906 argv is a list or tuple of strings. */
4907
Ross Lagerwall7807c352011-03-17 20:20:30 +02004908 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4909 PyErr_SetString(PyExc_TypeError,
4910 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004911 return NULL;
4912 }
4913 argc = PySequence_Size(argv);
4914 if (argc < 1) {
4915 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004916 return NULL;
4917 }
4918
4919 argvlist = parse_arglist(argv, &argc);
4920 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004921 return NULL;
4922 }
Steve Dowerbce26262016-11-19 19:17:26 -08004923 if (!argvlist[0][0]) {
4924 PyErr_SetString(PyExc_ValueError,
4925 "execv() arg 2 first element cannot be empty");
4926 free_string_array(argvlist, argc);
4927 return NULL;
4928 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004929
Steve Dowerbce26262016-11-19 19:17:26 -08004930 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004931#ifdef HAVE_WEXECV
4932 _wexecv(path->wide, argvlist);
4933#else
4934 execv(path->narrow, argvlist);
4935#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004936 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004937
4938 /* If we get here it's definitely an error */
4939
4940 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004941 return posix_error();
4942}
4943
Larry Hastings2f936352014-08-05 14:04:04 +10004944
4945/*[clinic input]
4946os.execve
4947
4948 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4949 Path of executable file.
4950 argv: object
4951 Tuple or list of strings.
4952 env: object
4953 Dictionary of strings mapping to strings.
4954
4955Execute an executable path with arguments, replacing current process.
4956[clinic start generated code]*/
4957
Larry Hastings2f936352014-08-05 14:04:04 +10004958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004959os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4960/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004961{
Steve Dowercc16be82016-09-08 10:35:16 -07004962 EXECV_CHAR **argvlist = NULL;
4963 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004964 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004965
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 /* execve has three arguments: (path, argv, env), where
4967 argv is a list or tuple of strings and env is a dictionary
4968 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004969
Ross Lagerwall7807c352011-03-17 20:20:30 +02004970 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004971 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004972 "execve: argv must be a tuple or list");
4973 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08004976 if (argc < 1) {
4977 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
4978 return NULL;
4979 }
4980
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 if (!PyMapping_Check(env)) {
4982 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983 "execve: environment must be a mapping object");
4984 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004986
Ross Lagerwall7807c352011-03-17 20:20:30 +02004987 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004988 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004989 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 }
Steve Dowerbce26262016-11-19 19:17:26 -08004991 if (!argvlist[0][0]) {
4992 PyErr_SetString(PyExc_ValueError,
4993 "execve: argv first element cannot be empty");
4994 goto fail;
4995 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004996
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 envlist = parse_envlist(env, &envc);
4998 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999 goto fail;
5000
Steve Dowerbce26262016-11-19 19:17:26 -08005001 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005002#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005003 if (path->fd > -1)
5004 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005005 else
5006#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005007#ifdef HAVE_WEXECV
5008 _wexecve(path->wide, argvlist, envlist);
5009#else
Larry Hastings2f936352014-08-05 14:04:04 +10005010 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005011#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005012 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013
5014 /* If we get here it's definitely an error */
5015
Larry Hastings2f936352014-08-05 14:04:04 +10005016 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005017
Steve Dowercc16be82016-09-08 10:35:16 -07005018 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005020 if (argvlist)
5021 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005022 return NULL;
5023}
Steve Dowercc16be82016-09-08 10:35:16 -07005024
Larry Hastings9cf065c2012-06-22 16:30:09 -07005025#endif /* HAVE_EXECV */
5026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005027
Steve Dowercc16be82016-09-08 10:35:16 -07005028#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005029/*[clinic input]
5030os.spawnv
5031
5032 mode: int
5033 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005034 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005035 Path of executable file.
5036 argv: object
5037 Tuple or list of strings.
5038 /
5039
5040Execute the program specified by path in a new process.
5041[clinic start generated code]*/
5042
Larry Hastings2f936352014-08-05 14:04:04 +10005043static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005044os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5045/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005046{
Steve Dowercc16be82016-09-08 10:35:16 -07005047 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005048 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005050 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005052
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 /* spawnv has three arguments: (mode, path, argv), where
5054 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005055
Victor Stinner8c62be82010-05-06 00:08:46 +00005056 if (PyList_Check(argv)) {
5057 argc = PyList_Size(argv);
5058 getitem = PyList_GetItem;
5059 }
5060 else if (PyTuple_Check(argv)) {
5061 argc = PyTuple_Size(argv);
5062 getitem = PyTuple_GetItem;
5063 }
5064 else {
5065 PyErr_SetString(PyExc_TypeError,
5066 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 return NULL;
5068 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005069 if (argc == 0) {
5070 PyErr_SetString(PyExc_ValueError,
5071 "spawnv() arg 2 cannot be empty");
5072 return NULL;
5073 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005074
Steve Dowercc16be82016-09-08 10:35:16 -07005075 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 return PyErr_NoMemory();
5078 }
5079 for (i = 0; i < argc; i++) {
5080 if (!fsconvert_strdup((*getitem)(argv, i),
5081 &argvlist[i])) {
5082 free_string_array(argvlist, i);
5083 PyErr_SetString(
5084 PyExc_TypeError,
5085 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 return NULL;
5087 }
Steve Dower93ff8722016-11-19 19:03:54 -08005088 if (i == 0 && !argvlist[0][0]) {
5089 free_string_array(argvlist, i);
5090 PyErr_SetString(
5091 PyExc_ValueError,
5092 "spawnv() arg 2 first element cannot be empty");
5093 return NULL;
5094 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 }
5096 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005097
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 if (mode == _OLD_P_OVERLAY)
5099 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005100
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005102 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005103#ifdef HAVE_WSPAWNV
5104 spawnval = _wspawnv(mode, path->wide, argvlist);
5105#else
5106 spawnval = _spawnv(mode, path->narrow, argvlist);
5107#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005108 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005112
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 if (spawnval == -1)
5114 return posix_error();
5115 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005116 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005117}
5118
5119
Larry Hastings2f936352014-08-05 14:04:04 +10005120/*[clinic input]
5121os.spawnve
5122
5123 mode: int
5124 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005125 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005126 Path of executable file.
5127 argv: object
5128 Tuple or list of strings.
5129 env: object
5130 Dictionary of strings mapping to strings.
5131 /
5132
5133Execute the program specified by path in a new process.
5134[clinic start generated code]*/
5135
Larry Hastings2f936352014-08-05 14:04:04 +10005136static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005137os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005138 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005139/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005140{
Steve Dowercc16be82016-09-08 10:35:16 -07005141 EXECV_CHAR **argvlist;
5142 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005144 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005145 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5147 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005148
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 /* spawnve has four arguments: (mode, path, argv, env), where
5150 argv is a list or tuple of strings and env is a dictionary
5151 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005152
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (PyList_Check(argv)) {
5154 argc = PyList_Size(argv);
5155 getitem = PyList_GetItem;
5156 }
5157 else if (PyTuple_Check(argv)) {
5158 argc = PyTuple_Size(argv);
5159 getitem = PyTuple_GetItem;
5160 }
5161 else {
5162 PyErr_SetString(PyExc_TypeError,
5163 "spawnve() arg 2 must be a tuple or list");
5164 goto fail_0;
5165 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005166 if (argc == 0) {
5167 PyErr_SetString(PyExc_ValueError,
5168 "spawnve() arg 2 cannot be empty");
5169 goto fail_0;
5170 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 if (!PyMapping_Check(env)) {
5172 PyErr_SetString(PyExc_TypeError,
5173 "spawnve() arg 3 must be a mapping object");
5174 goto fail_0;
5175 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005176
Steve Dowercc16be82016-09-08 10:35:16 -07005177 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 if (argvlist == NULL) {
5179 PyErr_NoMemory();
5180 goto fail_0;
5181 }
5182 for (i = 0; i < argc; i++) {
5183 if (!fsconvert_strdup((*getitem)(argv, i),
5184 &argvlist[i]))
5185 {
5186 lastarg = i;
5187 goto fail_1;
5188 }
Steve Dowerbce26262016-11-19 19:17:26 -08005189 if (i == 0 && !argvlist[0][0]) {
5190 lastarg = i;
5191 PyErr_SetString(
5192 PyExc_ValueError,
5193 "spawnv() arg 2 first element cannot be empty");
5194 goto fail_1;
5195 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 }
5197 lastarg = argc;
5198 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 envlist = parse_envlist(env, &envc);
5201 if (envlist == NULL)
5202 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005203
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 if (mode == _OLD_P_OVERLAY)
5205 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005206
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005208 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005209#ifdef HAVE_WSPAWNV
5210 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5211#else
5212 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5213#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005214 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005215 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005216
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 if (spawnval == -1)
5218 (void) posix_error();
5219 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005220 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005221
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 while (--envc >= 0)
5223 PyMem_DEL(envlist[envc]);
5224 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005225 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005227 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005229}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005230
Guido van Rossuma1065681999-01-25 23:20:23 +00005231#endif /* HAVE_SPAWNV */
5232
5233
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005234#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005235/*[clinic input]
5236os.fork1
5237
5238Fork a child process with a single multiplexed (i.e., not bound) thread.
5239
5240Return 0 to child process and PID of child to parent process.
5241[clinic start generated code]*/
5242
Larry Hastings2f936352014-08-05 14:04:04 +10005243static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005244os_fork1_impl(PyObject *module)
5245/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005246{
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 pid_t pid;
5248 int result = 0;
5249 _PyImport_AcquireLock();
5250 pid = fork1();
5251 if (pid == 0) {
5252 /* child: this clobbers and resets the import lock. */
5253 PyOS_AfterFork();
5254 } else {
5255 /* parent: release the import lock. */
5256 result = _PyImport_ReleaseLock();
5257 }
5258 if (pid == -1)
5259 return posix_error();
5260 if (result < 0) {
5261 /* Don't clobber the OSError if the fork failed. */
5262 PyErr_SetString(PyExc_RuntimeError,
5263 "not holding the import lock");
5264 return NULL;
5265 }
5266 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005267}
Larry Hastings2f936352014-08-05 14:04:04 +10005268#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005269
5270
Guido van Rossumad0ee831995-03-01 10:34:45 +00005271#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005272/*[clinic input]
5273os.fork
5274
5275Fork a child process.
5276
5277Return 0 to child process and PID of child to parent process.
5278[clinic start generated code]*/
5279
Larry Hastings2f936352014-08-05 14:04:04 +10005280static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005281os_fork_impl(PyObject *module)
5282/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005283{
Victor Stinner8c62be82010-05-06 00:08:46 +00005284 pid_t pid;
5285 int result = 0;
5286 _PyImport_AcquireLock();
5287 pid = fork();
5288 if (pid == 0) {
5289 /* child: this clobbers and resets the import lock. */
5290 PyOS_AfterFork();
5291 } else {
5292 /* parent: release the import lock. */
5293 result = _PyImport_ReleaseLock();
5294 }
5295 if (pid == -1)
5296 return posix_error();
5297 if (result < 0) {
5298 /* Don't clobber the OSError if the fork failed. */
5299 PyErr_SetString(PyExc_RuntimeError,
5300 "not holding the import lock");
5301 return NULL;
5302 }
5303 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005304}
Larry Hastings2f936352014-08-05 14:04:04 +10005305#endif /* HAVE_FORK */
5306
Guido van Rossum85e3b011991-06-03 12:42:10 +00005307
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005308#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005309#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005310/*[clinic input]
5311os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005312
Larry Hastings2f936352014-08-05 14:04:04 +10005313 policy: int
5314
5315Get the maximum scheduling priority for policy.
5316[clinic start generated code]*/
5317
Larry Hastings2f936352014-08-05 14:04:04 +10005318static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005319os_sched_get_priority_max_impl(PyObject *module, int policy)
5320/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005321{
5322 int max;
5323
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005324 max = sched_get_priority_max(policy);
5325 if (max < 0)
5326 return posix_error();
5327 return PyLong_FromLong(max);
5328}
5329
Larry Hastings2f936352014-08-05 14:04:04 +10005330
5331/*[clinic input]
5332os.sched_get_priority_min
5333
5334 policy: int
5335
5336Get the minimum scheduling priority for policy.
5337[clinic start generated code]*/
5338
Larry Hastings2f936352014-08-05 14:04:04 +10005339static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005340os_sched_get_priority_min_impl(PyObject *module, int policy)
5341/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005342{
5343 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005344 if (min < 0)
5345 return posix_error();
5346 return PyLong_FromLong(min);
5347}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005348#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5349
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005350
Larry Hastings2f936352014-08-05 14:04:04 +10005351#ifdef HAVE_SCHED_SETSCHEDULER
5352/*[clinic input]
5353os.sched_getscheduler
5354 pid: pid_t
5355 /
5356
5357Get the scheduling policy for the process identifiedy by pid.
5358
5359Passing 0 for pid returns the scheduling policy for the calling process.
5360[clinic start generated code]*/
5361
Larry Hastings2f936352014-08-05 14:04:04 +10005362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005363os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5364/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005365{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005366 int policy;
5367
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005368 policy = sched_getscheduler(pid);
5369 if (policy < 0)
5370 return posix_error();
5371 return PyLong_FromLong(policy);
5372}
Larry Hastings2f936352014-08-05 14:04:04 +10005373#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005374
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005375
5376#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005377/*[clinic input]
5378class os.sched_param "PyObject *" "&SchedParamType"
5379
5380@classmethod
5381os.sched_param.__new__
5382
5383 sched_priority: object
5384 A scheduling parameter.
5385
5386Current has only one field: sched_priority");
5387[clinic start generated code]*/
5388
Larry Hastings2f936352014-08-05 14:04:04 +10005389static PyObject *
5390os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005391/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005392{
5393 PyObject *res;
5394
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005395 res = PyStructSequence_New(type);
5396 if (!res)
5397 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005398 Py_INCREF(sched_priority);
5399 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005400 return res;
5401}
5402
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005403
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005404PyDoc_VAR(os_sched_param__doc__);
5405
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005406static PyStructSequence_Field sched_param_fields[] = {
5407 {"sched_priority", "the scheduling priority"},
5408 {0}
5409};
5410
5411static PyStructSequence_Desc sched_param_desc = {
5412 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005413 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005414 sched_param_fields,
5415 1
5416};
5417
5418static int
5419convert_sched_param(PyObject *param, struct sched_param *res)
5420{
5421 long priority;
5422
5423 if (Py_TYPE(param) != &SchedParamType) {
5424 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5425 return 0;
5426 }
5427 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5428 if (priority == -1 && PyErr_Occurred())
5429 return 0;
5430 if (priority > INT_MAX || priority < INT_MIN) {
5431 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5432 return 0;
5433 }
5434 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5435 return 1;
5436}
Larry Hastings2f936352014-08-05 14:04:04 +10005437#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005438
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005439
5440#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005441/*[clinic input]
5442os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005443
Larry Hastings2f936352014-08-05 14:04:04 +10005444 pid: pid_t
5445 policy: int
5446 param: sched_param
5447 /
5448
5449Set the scheduling policy for the process identified by pid.
5450
5451If pid is 0, the calling process is changed.
5452param is an instance of sched_param.
5453[clinic start generated code]*/
5454
Larry Hastings2f936352014-08-05 14:04:04 +10005455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005456os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005457 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005458/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005459{
Jesus Cea9c822272011-09-10 01:40:52 +02005460 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005461 ** sched_setscheduler() returns 0 in Linux, but the previous
5462 ** scheduling policy under Solaris/Illumos, and others.
5463 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005464 */
Larry Hastings2f936352014-08-05 14:04:04 +10005465 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005466 return posix_error();
5467 Py_RETURN_NONE;
5468}
Larry Hastings2f936352014-08-05 14:04:04 +10005469#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005470
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005471
5472#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005473/*[clinic input]
5474os.sched_getparam
5475 pid: pid_t
5476 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005477
Larry Hastings2f936352014-08-05 14:04:04 +10005478Returns scheduling parameters for the process identified by pid.
5479
5480If pid is 0, returns parameters for the calling process.
5481Return value is an instance of sched_param.
5482[clinic start generated code]*/
5483
Larry Hastings2f936352014-08-05 14:04:04 +10005484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005485os_sched_getparam_impl(PyObject *module, pid_t pid)
5486/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005487{
5488 struct sched_param param;
5489 PyObject *result;
5490 PyObject *priority;
5491
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492 if (sched_getparam(pid, &param))
5493 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005494 result = PyStructSequence_New(&SchedParamType);
5495 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496 return NULL;
5497 priority = PyLong_FromLong(param.sched_priority);
5498 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005499 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005500 return NULL;
5501 }
Larry Hastings2f936352014-08-05 14:04:04 +10005502 PyStructSequence_SET_ITEM(result, 0, priority);
5503 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005504}
5505
Larry Hastings2f936352014-08-05 14:04:04 +10005506
5507/*[clinic input]
5508os.sched_setparam
5509 pid: pid_t
5510 param: sched_param
5511 /
5512
5513Set scheduling parameters for the process identified by pid.
5514
5515If pid is 0, sets parameters for the calling process.
5516param should be an instance of sched_param.
5517[clinic start generated code]*/
5518
Larry Hastings2f936352014-08-05 14:04:04 +10005519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005520os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005521 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005522/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005523{
5524 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005525 return posix_error();
5526 Py_RETURN_NONE;
5527}
Larry Hastings2f936352014-08-05 14:04:04 +10005528#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005529
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005530
5531#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005532/*[clinic input]
5533os.sched_rr_get_interval -> double
5534 pid: pid_t
5535 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005536
Larry Hastings2f936352014-08-05 14:04:04 +10005537Return the round-robin quantum for the process identified by pid, in seconds.
5538
5539Value returned is a float.
5540[clinic start generated code]*/
5541
Larry Hastings2f936352014-08-05 14:04:04 +10005542static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005543os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5544/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005545{
5546 struct timespec interval;
5547 if (sched_rr_get_interval(pid, &interval)) {
5548 posix_error();
5549 return -1.0;
5550 }
5551 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5552}
5553#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005554
Larry Hastings2f936352014-08-05 14:04:04 +10005555
5556/*[clinic input]
5557os.sched_yield
5558
5559Voluntarily relinquish the CPU.
5560[clinic start generated code]*/
5561
Larry Hastings2f936352014-08-05 14:04:04 +10005562static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005563os_sched_yield_impl(PyObject *module)
5564/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005565{
5566 if (sched_yield())
5567 return posix_error();
5568 Py_RETURN_NONE;
5569}
5570
Benjamin Peterson2740af82011-08-02 17:41:34 -05005571#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005572/* The minimum number of CPUs allocated in a cpu_set_t */
5573static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005574
Larry Hastings2f936352014-08-05 14:04:04 +10005575/*[clinic input]
5576os.sched_setaffinity
5577 pid: pid_t
5578 mask : object
5579 /
5580
5581Set the CPU affinity of the process identified by pid to mask.
5582
5583mask should be an iterable of integers identifying CPUs.
5584[clinic start generated code]*/
5585
Larry Hastings2f936352014-08-05 14:04:04 +10005586static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005587os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5588/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005589{
Antoine Pitrou84869872012-08-04 16:16:35 +02005590 int ncpus;
5591 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005592 cpu_set_t *cpu_set = NULL;
5593 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005594
Larry Hastings2f936352014-08-05 14:04:04 +10005595 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005596 if (iterator == NULL)
5597 return NULL;
5598
5599 ncpus = NCPUS_START;
5600 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005601 cpu_set = CPU_ALLOC(ncpus);
5602 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005603 PyErr_NoMemory();
5604 goto error;
5605 }
Larry Hastings2f936352014-08-05 14:04:04 +10005606 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005607
5608 while ((item = PyIter_Next(iterator))) {
5609 long cpu;
5610 if (!PyLong_Check(item)) {
5611 PyErr_Format(PyExc_TypeError,
5612 "expected an iterator of ints, "
5613 "but iterator yielded %R",
5614 Py_TYPE(item));
5615 Py_DECREF(item);
5616 goto error;
5617 }
5618 cpu = PyLong_AsLong(item);
5619 Py_DECREF(item);
5620 if (cpu < 0) {
5621 if (!PyErr_Occurred())
5622 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5623 goto error;
5624 }
5625 if (cpu > INT_MAX - 1) {
5626 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5627 goto error;
5628 }
5629 if (cpu >= ncpus) {
5630 /* Grow CPU mask to fit the CPU number */
5631 int newncpus = ncpus;
5632 cpu_set_t *newmask;
5633 size_t newsetsize;
5634 while (newncpus <= cpu) {
5635 if (newncpus > INT_MAX / 2)
5636 newncpus = cpu + 1;
5637 else
5638 newncpus = newncpus * 2;
5639 }
5640 newmask = CPU_ALLOC(newncpus);
5641 if (newmask == NULL) {
5642 PyErr_NoMemory();
5643 goto error;
5644 }
5645 newsetsize = CPU_ALLOC_SIZE(newncpus);
5646 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005647 memcpy(newmask, cpu_set, setsize);
5648 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005649 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005650 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005651 ncpus = newncpus;
5652 }
Larry Hastings2f936352014-08-05 14:04:04 +10005653 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005654 }
5655 Py_CLEAR(iterator);
5656
Larry Hastings2f936352014-08-05 14:04:04 +10005657 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005658 posix_error();
5659 goto error;
5660 }
Larry Hastings2f936352014-08-05 14:04:04 +10005661 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005662 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005663
5664error:
Larry Hastings2f936352014-08-05 14:04:04 +10005665 if (cpu_set)
5666 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005667 Py_XDECREF(iterator);
5668 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005669}
5670
Larry Hastings2f936352014-08-05 14:04:04 +10005671
5672/*[clinic input]
5673os.sched_getaffinity
5674 pid: pid_t
5675 /
5676
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005677Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005678
5679The affinity is returned as a set of CPU identifiers.
5680[clinic start generated code]*/
5681
Larry Hastings2f936352014-08-05 14:04:04 +10005682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005683os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005684/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005685{
Antoine Pitrou84869872012-08-04 16:16:35 +02005686 int cpu, ncpus, count;
5687 size_t setsize;
5688 cpu_set_t *mask = NULL;
5689 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005690
Antoine Pitrou84869872012-08-04 16:16:35 +02005691 ncpus = NCPUS_START;
5692 while (1) {
5693 setsize = CPU_ALLOC_SIZE(ncpus);
5694 mask = CPU_ALLOC(ncpus);
5695 if (mask == NULL)
5696 return PyErr_NoMemory();
5697 if (sched_getaffinity(pid, setsize, mask) == 0)
5698 break;
5699 CPU_FREE(mask);
5700 if (errno != EINVAL)
5701 return posix_error();
5702 if (ncpus > INT_MAX / 2) {
5703 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5704 "a large enough CPU set");
5705 return NULL;
5706 }
5707 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005708 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005709
5710 res = PySet_New(NULL);
5711 if (res == NULL)
5712 goto error;
5713 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5714 if (CPU_ISSET_S(cpu, setsize, mask)) {
5715 PyObject *cpu_num = PyLong_FromLong(cpu);
5716 --count;
5717 if (cpu_num == NULL)
5718 goto error;
5719 if (PySet_Add(res, cpu_num)) {
5720 Py_DECREF(cpu_num);
5721 goto error;
5722 }
5723 Py_DECREF(cpu_num);
5724 }
5725 }
5726 CPU_FREE(mask);
5727 return res;
5728
5729error:
5730 if (mask)
5731 CPU_FREE(mask);
5732 Py_XDECREF(res);
5733 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005734}
5735
Benjamin Peterson2740af82011-08-02 17:41:34 -05005736#endif /* HAVE_SCHED_SETAFFINITY */
5737
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005738#endif /* HAVE_SCHED_H */
5739
Larry Hastings2f936352014-08-05 14:04:04 +10005740
Neal Norwitzb59798b2003-03-21 01:43:31 +00005741/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005742/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5743#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005744#define DEV_PTY_FILE "/dev/ptc"
5745#define HAVE_DEV_PTMX
5746#else
5747#define DEV_PTY_FILE "/dev/ptmx"
5748#endif
5749
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005750#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005751#ifdef HAVE_PTY_H
5752#include <pty.h>
5753#else
5754#ifdef HAVE_LIBUTIL_H
5755#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005756#else
5757#ifdef HAVE_UTIL_H
5758#include <util.h>
5759#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005760#endif /* HAVE_LIBUTIL_H */
5761#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005762#ifdef HAVE_STROPTS_H
5763#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005764#endif
5765#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005766
Larry Hastings2f936352014-08-05 14:04:04 +10005767
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005768#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005769/*[clinic input]
5770os.openpty
5771
5772Open a pseudo-terminal.
5773
5774Return a tuple of (master_fd, slave_fd) containing open file descriptors
5775for both the master and slave ends.
5776[clinic start generated code]*/
5777
Larry Hastings2f936352014-08-05 14:04:04 +10005778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005779os_openpty_impl(PyObject *module)
5780/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005781{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005782 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005783#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005784 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005785#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005786#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005787 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005788#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005790#endif
5791#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005792
Thomas Wouters70c21a12000-07-14 14:28:33 +00005793#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005794 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005795 goto posix_error;
5796
5797 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5798 goto error;
5799 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5800 goto error;
5801
Neal Norwitzb59798b2003-03-21 01:43:31 +00005802#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005803 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5804 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005805 goto posix_error;
5806 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5807 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005808
Victor Stinnerdaf45552013-08-28 00:53:59 +02005809 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005810 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005811 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005812
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005813#else
Victor Stinner000de532013-11-25 23:19:58 +01005814 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005816 goto posix_error;
5817
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005819
Victor Stinner8c62be82010-05-06 00:08:46 +00005820 /* change permission of slave */
5821 if (grantpt(master_fd) < 0) {
5822 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005823 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005824 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005825
Victor Stinner8c62be82010-05-06 00:08:46 +00005826 /* unlock slave */
5827 if (unlockpt(master_fd) < 0) {
5828 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005829 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005831
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005833
Victor Stinner8c62be82010-05-06 00:08:46 +00005834 slave_name = ptsname(master_fd); /* get name of slave */
5835 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005836 goto posix_error;
5837
5838 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005839 if (slave_fd == -1)
5840 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005841
5842 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5843 goto posix_error;
5844
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005845#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005846 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5847 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005848#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005849 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005850#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005851#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005852#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005853
Victor Stinner8c62be82010-05-06 00:08:46 +00005854 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005855
Victor Stinnerdaf45552013-08-28 00:53:59 +02005856posix_error:
5857 posix_error();
5858error:
5859 if (master_fd != -1)
5860 close(master_fd);
5861 if (slave_fd != -1)
5862 close(slave_fd);
5863 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005864}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005865#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005866
Larry Hastings2f936352014-08-05 14:04:04 +10005867
Fred Drake8cef4cf2000-06-28 16:40:38 +00005868#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005869/*[clinic input]
5870os.forkpty
5871
5872Fork a new process with a new pseudo-terminal as controlling tty.
5873
5874Returns a tuple of (pid, master_fd).
5875Like fork(), return pid of 0 to the child process,
5876and pid of child to the parent process.
5877To both, return fd of newly opened pseudo-terminal.
5878[clinic start generated code]*/
5879
Larry Hastings2f936352014-08-05 14:04:04 +10005880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005881os_forkpty_impl(PyObject *module)
5882/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005883{
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 int master_fd = -1, result = 0;
5885 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005886
Victor Stinner8c62be82010-05-06 00:08:46 +00005887 _PyImport_AcquireLock();
5888 pid = forkpty(&master_fd, NULL, NULL, NULL);
5889 if (pid == 0) {
5890 /* child: this clobbers and resets the import lock. */
5891 PyOS_AfterFork();
5892 } else {
5893 /* parent: release the import lock. */
5894 result = _PyImport_ReleaseLock();
5895 }
5896 if (pid == -1)
5897 return posix_error();
5898 if (result < 0) {
5899 /* Don't clobber the OSError if the fork failed. */
5900 PyErr_SetString(PyExc_RuntimeError,
5901 "not holding the import lock");
5902 return NULL;
5903 }
5904 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005905}
Larry Hastings2f936352014-08-05 14:04:04 +10005906#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005907
Ross Lagerwall7807c352011-03-17 20:20:30 +02005908
Guido van Rossumad0ee831995-03-01 10:34:45 +00005909#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005910/*[clinic input]
5911os.getegid
5912
5913Return the current process's effective group id.
5914[clinic start generated code]*/
5915
Larry Hastings2f936352014-08-05 14:04:04 +10005916static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005917os_getegid_impl(PyObject *module)
5918/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005919{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005920 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005921}
Larry Hastings2f936352014-08-05 14:04:04 +10005922#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005924
Guido van Rossumad0ee831995-03-01 10:34:45 +00005925#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005926/*[clinic input]
5927os.geteuid
5928
5929Return the current process's effective user id.
5930[clinic start generated code]*/
5931
Larry Hastings2f936352014-08-05 14:04:04 +10005932static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005933os_geteuid_impl(PyObject *module)
5934/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005935{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005936 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005937}
Larry Hastings2f936352014-08-05 14:04:04 +10005938#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005940
Guido van Rossumad0ee831995-03-01 10:34:45 +00005941#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005942/*[clinic input]
5943os.getgid
5944
5945Return the current process's group id.
5946[clinic start generated code]*/
5947
Larry Hastings2f936352014-08-05 14:04:04 +10005948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005949os_getgid_impl(PyObject *module)
5950/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005951{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005952 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005953}
Larry Hastings2f936352014-08-05 14:04:04 +10005954#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005956
Berker Peksag39404992016-09-15 20:45:16 +03005957#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10005958/*[clinic input]
5959os.getpid
5960
5961Return the current process id.
5962[clinic start generated code]*/
5963
Larry Hastings2f936352014-08-05 14:04:04 +10005964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005965os_getpid_impl(PyObject *module)
5966/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005967{
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005969}
Berker Peksag39404992016-09-15 20:45:16 +03005970#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005971
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005972#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005973
5974/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005975PyDoc_STRVAR(posix_getgrouplist__doc__,
5976"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5977Returns a list of groups to which a user belongs.\n\n\
5978 user: username to lookup\n\
5979 group: base group id of the user");
5980
5981static PyObject *
5982posix_getgrouplist(PyObject *self, PyObject *args)
5983{
5984#ifdef NGROUPS_MAX
5985#define MAX_GROUPS NGROUPS_MAX
5986#else
5987 /* defined to be 16 on Solaris7, so this should be a small number */
5988#define MAX_GROUPS 64
5989#endif
5990
5991 const char *user;
5992 int i, ngroups;
5993 PyObject *list;
5994#ifdef __APPLE__
5995 int *groups, basegid;
5996#else
5997 gid_t *groups, basegid;
5998#endif
5999 ngroups = MAX_GROUPS;
6000
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006001#ifdef __APPLE__
6002 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006003 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006004#else
6005 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6006 _Py_Gid_Converter, &basegid))
6007 return NULL;
6008#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006009
6010#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006011 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006012#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006013 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006014#endif
6015 if (groups == NULL)
6016 return PyErr_NoMemory();
6017
6018 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6019 PyMem_Del(groups);
6020 return posix_error();
6021 }
6022
6023 list = PyList_New(ngroups);
6024 if (list == NULL) {
6025 PyMem_Del(groups);
6026 return NULL;
6027 }
6028
6029 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006030#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006031 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006032#else
6033 PyObject *o = _PyLong_FromGid(groups[i]);
6034#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006035 if (o == NULL) {
6036 Py_DECREF(list);
6037 PyMem_Del(groups);
6038 return NULL;
6039 }
6040 PyList_SET_ITEM(list, i, o);
6041 }
6042
6043 PyMem_Del(groups);
6044
6045 return list;
6046}
Larry Hastings2f936352014-08-05 14:04:04 +10006047#endif /* HAVE_GETGROUPLIST */
6048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006049
Fred Drakec9680921999-12-13 16:37:25 +00006050#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006051/*[clinic input]
6052os.getgroups
6053
6054Return list of supplemental group IDs for the process.
6055[clinic start generated code]*/
6056
Larry Hastings2f936352014-08-05 14:04:04 +10006057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006058os_getgroups_impl(PyObject *module)
6059/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006060{
6061 PyObject *result = NULL;
6062
Fred Drakec9680921999-12-13 16:37:25 +00006063#ifdef NGROUPS_MAX
6064#define MAX_GROUPS NGROUPS_MAX
6065#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006067#define MAX_GROUPS 64
6068#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006070
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006071 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006072 * This is a helper variable to store the intermediate result when
6073 * that happens.
6074 *
6075 * To keep the code readable the OSX behaviour is unconditional,
6076 * according to the POSIX spec this should be safe on all unix-y
6077 * systems.
6078 */
6079 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006080 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006081
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006082#ifdef __APPLE__
6083 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6084 * there are more groups than can fit in grouplist. Therefore, on OS X
6085 * always first call getgroups with length 0 to get the actual number
6086 * of groups.
6087 */
6088 n = getgroups(0, NULL);
6089 if (n < 0) {
6090 return posix_error();
6091 } else if (n <= MAX_GROUPS) {
6092 /* groups will fit in existing array */
6093 alt_grouplist = grouplist;
6094 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006095 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006096 if (alt_grouplist == NULL) {
6097 errno = EINVAL;
6098 return posix_error();
6099 }
6100 }
6101
6102 n = getgroups(n, alt_grouplist);
6103 if (n == -1) {
6104 if (alt_grouplist != grouplist) {
6105 PyMem_Free(alt_grouplist);
6106 }
6107 return posix_error();
6108 }
6109#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006111 if (n < 0) {
6112 if (errno == EINVAL) {
6113 n = getgroups(0, NULL);
6114 if (n == -1) {
6115 return posix_error();
6116 }
6117 if (n == 0) {
6118 /* Avoid malloc(0) */
6119 alt_grouplist = grouplist;
6120 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006121 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006122 if (alt_grouplist == NULL) {
6123 errno = EINVAL;
6124 return posix_error();
6125 }
6126 n = getgroups(n, alt_grouplist);
6127 if (n == -1) {
6128 PyMem_Free(alt_grouplist);
6129 return posix_error();
6130 }
6131 }
6132 } else {
6133 return posix_error();
6134 }
6135 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006136#endif
6137
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006138 result = PyList_New(n);
6139 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 int i;
6141 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006142 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006144 Py_DECREF(result);
6145 result = NULL;
6146 break;
Fred Drakec9680921999-12-13 16:37:25 +00006147 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006148 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006149 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006150 }
6151
6152 if (alt_grouplist != grouplist) {
6153 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006155
Fred Drakec9680921999-12-13 16:37:25 +00006156 return result;
6157}
Larry Hastings2f936352014-08-05 14:04:04 +10006158#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006159
Antoine Pitroub7572f02009-12-02 20:46:48 +00006160#ifdef HAVE_INITGROUPS
6161PyDoc_STRVAR(posix_initgroups__doc__,
6162"initgroups(username, gid) -> None\n\n\
6163Call the system initgroups() to initialize the group access list with all of\n\
6164the groups of which the specified username is a member, plus the specified\n\
6165group id.");
6166
Larry Hastings2f936352014-08-05 14:04:04 +10006167/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006168static PyObject *
6169posix_initgroups(PyObject *self, PyObject *args)
6170{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006171 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006172 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006173 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006174#ifdef __APPLE__
6175 int gid;
6176#else
6177 gid_t gid;
6178#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006179
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006180#ifdef __APPLE__
6181 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6182 PyUnicode_FSConverter, &oname,
6183 &gid))
6184#else
6185 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6186 PyUnicode_FSConverter, &oname,
6187 _Py_Gid_Converter, &gid))
6188#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006189 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006190 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006191
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006192 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006193 Py_DECREF(oname);
6194 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006195 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006196
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 Py_INCREF(Py_None);
6198 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006199}
Larry Hastings2f936352014-08-05 14:04:04 +10006200#endif /* HAVE_INITGROUPS */
6201
Antoine Pitroub7572f02009-12-02 20:46:48 +00006202
Martin v. Löwis606edc12002-06-13 21:09:11 +00006203#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006204/*[clinic input]
6205os.getpgid
6206
6207 pid: pid_t
6208
6209Call the system call getpgid(), and return the result.
6210[clinic start generated code]*/
6211
Larry Hastings2f936352014-08-05 14:04:04 +10006212static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006213os_getpgid_impl(PyObject *module, pid_t pid)
6214/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006215{
6216 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006217 if (pgid < 0)
6218 return posix_error();
6219 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006220}
6221#endif /* HAVE_GETPGID */
6222
6223
Guido van Rossumb6775db1994-08-01 11:34:53 +00006224#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006225/*[clinic input]
6226os.getpgrp
6227
6228Return the current process group id.
6229[clinic start generated code]*/
6230
Larry Hastings2f936352014-08-05 14:04:04 +10006231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006232os_getpgrp_impl(PyObject *module)
6233/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006234{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006235#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006237#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006239#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006240}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006241#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006243
Guido van Rossumb6775db1994-08-01 11:34:53 +00006244#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006245/*[clinic input]
6246os.setpgrp
6247
6248Make the current process the leader of its process group.
6249[clinic start generated code]*/
6250
Larry Hastings2f936352014-08-05 14:04:04 +10006251static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006252os_setpgrp_impl(PyObject *module)
6253/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006254{
Guido van Rossum64933891994-10-20 21:56:42 +00006255#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006257#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006259#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 return posix_error();
6261 Py_INCREF(Py_None);
6262 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006263}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006264#endif /* HAVE_SETPGRP */
6265
Guido van Rossumad0ee831995-03-01 10:34:45 +00006266#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006267
6268#ifdef MS_WINDOWS
6269#include <tlhelp32.h>
6270
6271static PyObject*
6272win32_getppid()
6273{
6274 HANDLE snapshot;
6275 pid_t mypid;
6276 PyObject* result = NULL;
6277 BOOL have_record;
6278 PROCESSENTRY32 pe;
6279
6280 mypid = getpid(); /* This function never fails */
6281
6282 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6283 if (snapshot == INVALID_HANDLE_VALUE)
6284 return PyErr_SetFromWindowsErr(GetLastError());
6285
6286 pe.dwSize = sizeof(pe);
6287 have_record = Process32First(snapshot, &pe);
6288 while (have_record) {
6289 if (mypid == (pid_t)pe.th32ProcessID) {
6290 /* We could cache the ulong value in a static variable. */
6291 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6292 break;
6293 }
6294
6295 have_record = Process32Next(snapshot, &pe);
6296 }
6297
6298 /* If our loop exits and our pid was not found (result will be NULL)
6299 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6300 * error anyway, so let's raise it. */
6301 if (!result)
6302 result = PyErr_SetFromWindowsErr(GetLastError());
6303
6304 CloseHandle(snapshot);
6305
6306 return result;
6307}
6308#endif /*MS_WINDOWS*/
6309
Larry Hastings2f936352014-08-05 14:04:04 +10006310
6311/*[clinic input]
6312os.getppid
6313
6314Return the parent's process id.
6315
6316If the parent process has already exited, Windows machines will still
6317return its id; others systems will return the id of the 'init' process (1).
6318[clinic start generated code]*/
6319
Larry Hastings2f936352014-08-05 14:04:04 +10006320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006321os_getppid_impl(PyObject *module)
6322/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006323{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006324#ifdef MS_WINDOWS
6325 return win32_getppid();
6326#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006327 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006328#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006329}
6330#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006332
Fred Drake12c6e2d1999-12-14 21:25:03 +00006333#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006334/*[clinic input]
6335os.getlogin
6336
6337Return the actual login name.
6338[clinic start generated code]*/
6339
Larry Hastings2f936352014-08-05 14:04:04 +10006340static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006341os_getlogin_impl(PyObject *module)
6342/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006343{
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006345#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006346 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006347 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006348
6349 if (GetUserNameW(user_name, &num_chars)) {
6350 /* num_chars is the number of unicode chars plus null terminator */
6351 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006352 }
6353 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006354 result = PyErr_SetFromWindowsErr(GetLastError());
6355#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 char *name;
6357 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006358
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 errno = 0;
6360 name = getlogin();
6361 if (name == NULL) {
6362 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006363 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006364 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006365 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 }
6367 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006368 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006370#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006371 return result;
6372}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006373#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006374
Larry Hastings2f936352014-08-05 14:04:04 +10006375
Guido van Rossumad0ee831995-03-01 10:34:45 +00006376#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006377/*[clinic input]
6378os.getuid
6379
6380Return the current process's user id.
6381[clinic start generated code]*/
6382
Larry Hastings2f936352014-08-05 14:04:04 +10006383static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006384os_getuid_impl(PyObject *module)
6385/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006386{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006387 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006388}
Larry Hastings2f936352014-08-05 14:04:04 +10006389#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006391
Brian Curtineb24d742010-04-12 17:16:38 +00006392#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006393#define HAVE_KILL
6394#endif /* MS_WINDOWS */
6395
6396#ifdef HAVE_KILL
6397/*[clinic input]
6398os.kill
6399
6400 pid: pid_t
6401 signal: Py_ssize_t
6402 /
6403
6404Kill a process with a signal.
6405[clinic start generated code]*/
6406
Larry Hastings2f936352014-08-05 14:04:04 +10006407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006408os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6409/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006410#ifndef MS_WINDOWS
6411{
6412 if (kill(pid, (int)signal) == -1)
6413 return posix_error();
6414 Py_RETURN_NONE;
6415}
6416#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006417{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006418 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006419 DWORD sig = (DWORD)signal;
6420 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006422
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 /* Console processes which share a common console can be sent CTRL+C or
6424 CTRL+BREAK events, provided they handle said events. */
6425 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006426 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 err = GetLastError();
6428 PyErr_SetFromWindowsErr(err);
6429 }
6430 else
6431 Py_RETURN_NONE;
6432 }
Brian Curtineb24d742010-04-12 17:16:38 +00006433
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6435 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006436 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 if (handle == NULL) {
6438 err = GetLastError();
6439 return PyErr_SetFromWindowsErr(err);
6440 }
Brian Curtineb24d742010-04-12 17:16:38 +00006441
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 if (TerminateProcess(handle, sig) == 0) {
6443 err = GetLastError();
6444 result = PyErr_SetFromWindowsErr(err);
6445 } else {
6446 Py_INCREF(Py_None);
6447 result = Py_None;
6448 }
Brian Curtineb24d742010-04-12 17:16:38 +00006449
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 CloseHandle(handle);
6451 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006452}
Larry Hastings2f936352014-08-05 14:04:04 +10006453#endif /* !MS_WINDOWS */
6454#endif /* HAVE_KILL */
6455
6456
6457#ifdef HAVE_KILLPG
6458/*[clinic input]
6459os.killpg
6460
6461 pgid: pid_t
6462 signal: int
6463 /
6464
6465Kill a process group with a signal.
6466[clinic start generated code]*/
6467
Larry Hastings2f936352014-08-05 14:04:04 +10006468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006469os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6470/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006471{
6472 /* XXX some man pages make the `pgid` parameter an int, others
6473 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6474 take the same type. Moreover, pid_t is always at least as wide as
6475 int (else compilation of this module fails), which is safe. */
6476 if (killpg(pgid, signal) == -1)
6477 return posix_error();
6478 Py_RETURN_NONE;
6479}
6480#endif /* HAVE_KILLPG */
6481
Brian Curtineb24d742010-04-12 17:16:38 +00006482
Guido van Rossumc0125471996-06-28 18:55:32 +00006483#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006484#ifdef HAVE_SYS_LOCK_H
6485#include <sys/lock.h>
6486#endif
6487
Larry Hastings2f936352014-08-05 14:04:04 +10006488/*[clinic input]
6489os.plock
6490 op: int
6491 /
6492
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006494[clinic start generated code]*/
6495
Larry Hastings2f936352014-08-05 14:04:04 +10006496static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006497os_plock_impl(PyObject *module, int op)
6498/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006499{
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 if (plock(op) == -1)
6501 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006502 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006503}
Larry Hastings2f936352014-08-05 14:04:04 +10006504#endif /* HAVE_PLOCK */
6505
Guido van Rossumc0125471996-06-28 18:55:32 +00006506
Guido van Rossumb6775db1994-08-01 11:34:53 +00006507#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006508/*[clinic input]
6509os.setuid
6510
6511 uid: uid_t
6512 /
6513
6514Set the current process's user id.
6515[clinic start generated code]*/
6516
Larry Hastings2f936352014-08-05 14:04:04 +10006517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006518os_setuid_impl(PyObject *module, uid_t uid)
6519/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006520{
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 if (setuid(uid) < 0)
6522 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006523 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006524}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006525#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006527
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006528#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006529/*[clinic input]
6530os.seteuid
6531
6532 euid: uid_t
6533 /
6534
6535Set the current process's effective user id.
6536[clinic start generated code]*/
6537
Larry Hastings2f936352014-08-05 14:04:04 +10006538static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006539os_seteuid_impl(PyObject *module, uid_t euid)
6540/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006541{
6542 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006544 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006545}
6546#endif /* HAVE_SETEUID */
6547
Larry Hastings2f936352014-08-05 14:04:04 +10006548
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006549#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006550/*[clinic input]
6551os.setegid
6552
6553 egid: gid_t
6554 /
6555
6556Set the current process's effective group id.
6557[clinic start generated code]*/
6558
Larry Hastings2f936352014-08-05 14:04:04 +10006559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006560os_setegid_impl(PyObject *module, gid_t egid)
6561/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006562{
6563 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006565 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006566}
6567#endif /* HAVE_SETEGID */
6568
Larry Hastings2f936352014-08-05 14:04:04 +10006569
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006570#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006571/*[clinic input]
6572os.setreuid
6573
6574 ruid: uid_t
6575 euid: uid_t
6576 /
6577
6578Set the current process's real and effective user ids.
6579[clinic start generated code]*/
6580
Larry Hastings2f936352014-08-05 14:04:04 +10006581static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006582os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6583/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006584{
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 if (setreuid(ruid, euid) < 0) {
6586 return posix_error();
6587 } else {
6588 Py_INCREF(Py_None);
6589 return Py_None;
6590 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006591}
6592#endif /* HAVE_SETREUID */
6593
Larry Hastings2f936352014-08-05 14:04:04 +10006594
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006595#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006596/*[clinic input]
6597os.setregid
6598
6599 rgid: gid_t
6600 egid: gid_t
6601 /
6602
6603Set the current process's real and effective group ids.
6604[clinic start generated code]*/
6605
Larry Hastings2f936352014-08-05 14:04:04 +10006606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006607os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6608/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006609{
6610 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006612 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006613}
6614#endif /* HAVE_SETREGID */
6615
Larry Hastings2f936352014-08-05 14:04:04 +10006616
Guido van Rossumb6775db1994-08-01 11:34:53 +00006617#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006618/*[clinic input]
6619os.setgid
6620 gid: gid_t
6621 /
6622
6623Set the current process's group id.
6624[clinic start generated code]*/
6625
Larry Hastings2f936352014-08-05 14:04:04 +10006626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006627os_setgid_impl(PyObject *module, gid_t gid)
6628/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006629{
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 if (setgid(gid) < 0)
6631 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006632 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006633}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006634#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006635
Larry Hastings2f936352014-08-05 14:04:04 +10006636
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006637#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006638/*[clinic input]
6639os.setgroups
6640
6641 groups: object
6642 /
6643
6644Set the groups of the current process to list.
6645[clinic start generated code]*/
6646
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006648os_setgroups(PyObject *module, PyObject *groups)
6649/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006650{
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 int i, len;
6652 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006653
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 if (!PySequence_Check(groups)) {
6655 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6656 return NULL;
6657 }
6658 len = PySequence_Size(groups);
6659 if (len > MAX_GROUPS) {
6660 PyErr_SetString(PyExc_ValueError, "too many groups");
6661 return NULL;
6662 }
6663 for(i = 0; i < len; i++) {
6664 PyObject *elem;
6665 elem = PySequence_GetItem(groups, i);
6666 if (!elem)
6667 return NULL;
6668 if (!PyLong_Check(elem)) {
6669 PyErr_SetString(PyExc_TypeError,
6670 "groups must be integers");
6671 Py_DECREF(elem);
6672 return NULL;
6673 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006674 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006675 Py_DECREF(elem);
6676 return NULL;
6677 }
6678 }
6679 Py_DECREF(elem);
6680 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006681
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 if (setgroups(len, grouplist) < 0)
6683 return posix_error();
6684 Py_INCREF(Py_None);
6685 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006686}
6687#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006688
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006689#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6690static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006691wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006692{
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 PyObject *result;
6694 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006695 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006696
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 if (pid == -1)
6698 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006699
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 if (struct_rusage == NULL) {
6701 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6702 if (m == NULL)
6703 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006704 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 Py_DECREF(m);
6706 if (struct_rusage == NULL)
6707 return NULL;
6708 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006709
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6711 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6712 if (!result)
6713 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006714
6715#ifndef doubletime
6716#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6717#endif
6718
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006720 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006722 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006723#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6725 SET_INT(result, 2, ru->ru_maxrss);
6726 SET_INT(result, 3, ru->ru_ixrss);
6727 SET_INT(result, 4, ru->ru_idrss);
6728 SET_INT(result, 5, ru->ru_isrss);
6729 SET_INT(result, 6, ru->ru_minflt);
6730 SET_INT(result, 7, ru->ru_majflt);
6731 SET_INT(result, 8, ru->ru_nswap);
6732 SET_INT(result, 9, ru->ru_inblock);
6733 SET_INT(result, 10, ru->ru_oublock);
6734 SET_INT(result, 11, ru->ru_msgsnd);
6735 SET_INT(result, 12, ru->ru_msgrcv);
6736 SET_INT(result, 13, ru->ru_nsignals);
6737 SET_INT(result, 14, ru->ru_nvcsw);
6738 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006739#undef SET_INT
6740
Victor Stinner8c62be82010-05-06 00:08:46 +00006741 if (PyErr_Occurred()) {
6742 Py_DECREF(result);
6743 return NULL;
6744 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006745
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006747}
6748#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6749
Larry Hastings2f936352014-08-05 14:04:04 +10006750
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006751#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006752/*[clinic input]
6753os.wait3
6754
6755 options: int
6756Wait for completion of a child process.
6757
6758Returns a tuple of information about the child process:
6759 (pid, status, rusage)
6760[clinic start generated code]*/
6761
Larry Hastings2f936352014-08-05 14:04:04 +10006762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006763os_wait3_impl(PyObject *module, int options)
6764/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006765{
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006768 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 WAIT_TYPE status;
6770 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006771
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006772 do {
6773 Py_BEGIN_ALLOW_THREADS
6774 pid = wait3(&status, options, &ru);
6775 Py_END_ALLOW_THREADS
6776 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6777 if (pid < 0)
6778 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006779
Victor Stinner4195b5c2012-02-08 23:03:19 +01006780 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006781}
6782#endif /* HAVE_WAIT3 */
6783
Larry Hastings2f936352014-08-05 14:04:04 +10006784
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006785#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006786/*[clinic input]
6787
6788os.wait4
6789
6790 pid: pid_t
6791 options: int
6792
6793Wait for completion of a specific child process.
6794
6795Returns a tuple of information about the child process:
6796 (pid, status, rusage)
6797[clinic start generated code]*/
6798
Larry Hastings2f936352014-08-05 14:04:04 +10006799static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006800os_wait4_impl(PyObject *module, pid_t pid, int options)
6801/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006802{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006803 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006805 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 WAIT_TYPE status;
6807 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006808
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006809 do {
6810 Py_BEGIN_ALLOW_THREADS
6811 res = wait4(pid, &status, options, &ru);
6812 Py_END_ALLOW_THREADS
6813 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6814 if (res < 0)
6815 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006816
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006817 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818}
6819#endif /* HAVE_WAIT4 */
6820
Larry Hastings2f936352014-08-05 14:04:04 +10006821
Ross Lagerwall7807c352011-03-17 20:20:30 +02006822#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006823/*[clinic input]
6824os.waitid
6825
6826 idtype: idtype_t
6827 Must be one of be P_PID, P_PGID or P_ALL.
6828 id: id_t
6829 The id to wait on.
6830 options: int
6831 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6832 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6833 /
6834
6835Returns the result of waiting for a process or processes.
6836
6837Returns either waitid_result or None if WNOHANG is specified and there are
6838no children in a waitable state.
6839[clinic start generated code]*/
6840
Larry Hastings2f936352014-08-05 14:04:04 +10006841static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006842os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6843/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006844{
6845 PyObject *result;
6846 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006847 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006848 siginfo_t si;
6849 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006850
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006851 do {
6852 Py_BEGIN_ALLOW_THREADS
6853 res = waitid(idtype, id, &si, options);
6854 Py_END_ALLOW_THREADS
6855 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6856 if (res < 0)
6857 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006858
6859 if (si.si_pid == 0)
6860 Py_RETURN_NONE;
6861
6862 result = PyStructSequence_New(&WaitidResultType);
6863 if (!result)
6864 return NULL;
6865
6866 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006867 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006868 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6869 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6870 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6871 if (PyErr_Occurred()) {
6872 Py_DECREF(result);
6873 return NULL;
6874 }
6875
6876 return result;
6877}
Larry Hastings2f936352014-08-05 14:04:04 +10006878#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006879
Larry Hastings2f936352014-08-05 14:04:04 +10006880
6881#if defined(HAVE_WAITPID)
6882/*[clinic input]
6883os.waitpid
6884 pid: pid_t
6885 options: int
6886 /
6887
6888Wait for completion of a given child process.
6889
6890Returns a tuple of information regarding the child process:
6891 (pid, status)
6892
6893The options argument is ignored on Windows.
6894[clinic start generated code]*/
6895
Larry Hastings2f936352014-08-05 14:04:04 +10006896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006897os_waitpid_impl(PyObject *module, pid_t pid, int options)
6898/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006899{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006900 pid_t res;
6901 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 WAIT_TYPE status;
6903 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006904
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006905 do {
6906 Py_BEGIN_ALLOW_THREADS
6907 res = waitpid(pid, &status, options);
6908 Py_END_ALLOW_THREADS
6909 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6910 if (res < 0)
6911 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006912
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006913 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006914}
Tim Petersab034fa2002-02-01 11:27:43 +00006915#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006916/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006917/*[clinic input]
6918os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006919 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006920 options: int
6921 /
6922
6923Wait for completion of a given process.
6924
6925Returns a tuple of information regarding the process:
6926 (pid, status << 8)
6927
6928The options argument is ignored on Windows.
6929[clinic start generated code]*/
6930
Larry Hastings2f936352014-08-05 14:04:04 +10006931static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006932os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006933/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006934{
6935 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006936 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006937 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006938
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006939 do {
6940 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006941 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006942 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006943 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006944 Py_END_ALLOW_THREADS
6945 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006946 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006947 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006950 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006951}
Larry Hastings2f936352014-08-05 14:04:04 +10006952#endif
6953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006954
Guido van Rossumad0ee831995-03-01 10:34:45 +00006955#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006956/*[clinic input]
6957os.wait
6958
6959Wait for completion of a child process.
6960
6961Returns a tuple of information about the child process:
6962 (pid, status)
6963[clinic start generated code]*/
6964
Larry Hastings2f936352014-08-05 14:04:04 +10006965static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006966os_wait_impl(PyObject *module)
6967/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006968{
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006970 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 WAIT_TYPE status;
6972 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006973
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006974 do {
6975 Py_BEGIN_ALLOW_THREADS
6976 pid = wait(&status);
6977 Py_END_ALLOW_THREADS
6978 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6979 if (pid < 0)
6980 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006981
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006983}
Larry Hastings2f936352014-08-05 14:04:04 +10006984#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006986
Larry Hastings9cf065c2012-06-22 16:30:09 -07006987#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6988PyDoc_STRVAR(readlink__doc__,
6989"readlink(path, *, dir_fd=None) -> path\n\n\
6990Return a string representing the path to which the symbolic link points.\n\
6991\n\
6992If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6993 and path should be relative; path will then be relative to that directory.\n\
6994dir_fd may not be implemented on your platform.\n\
6995 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006996#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006997
Guido van Rossumb6775db1994-08-01 11:34:53 +00006998#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006999
Larry Hastings2f936352014-08-05 14:04:04 +10007000/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007001static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007002posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007003{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007004 path_t path;
7005 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007006 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007007 ssize_t length;
7008 PyObject *return_value = NULL;
7009 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007010
Larry Hastings9cf065c2012-06-22 16:30:09 -07007011 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007012 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007013 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7014 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007015 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007017
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007019#ifdef HAVE_READLINKAT
7020 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007021 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007022 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007023#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007024 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007025 Py_END_ALLOW_THREADS
7026
7027 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007028 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007029 goto exit;
7030 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007031 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007032
7033 if (PyUnicode_Check(path.object))
7034 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7035 else
7036 return_value = PyBytes_FromStringAndSize(buffer, length);
7037exit:
7038 path_cleanup(&path);
7039 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007040}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007041
Guido van Rossumb6775db1994-08-01 11:34:53 +00007042#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007043
Larry Hastings2f936352014-08-05 14:04:04 +10007044#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7045
7046static PyObject *
7047win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7048{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007049 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007050 DWORD n_bytes_returned;
7051 DWORD io_result;
7052 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007053 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007054 HANDLE reparse_point_handle;
7055
Martin Panter70214ad2016-08-04 02:38:59 +00007056 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7057 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007058 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007059
7060 static char *keywords[] = {"path", "dir_fd", NULL};
7061
7062 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7063 &po,
7064 dir_fd_unavailable, &dir_fd
7065 ))
7066 return NULL;
7067
7068 path = PyUnicode_AsUnicode(po);
7069 if (path == NULL)
7070 return NULL;
7071
7072 /* First get a handle to the reparse point */
7073 Py_BEGIN_ALLOW_THREADS
7074 reparse_point_handle = CreateFileW(
7075 path,
7076 0,
7077 0,
7078 0,
7079 OPEN_EXISTING,
7080 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7081 0);
7082 Py_END_ALLOW_THREADS
7083
7084 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7085 return win32_error_object("readlink", po);
7086
7087 Py_BEGIN_ALLOW_THREADS
7088 /* New call DeviceIoControl to read the reparse point */
7089 io_result = DeviceIoControl(
7090 reparse_point_handle,
7091 FSCTL_GET_REPARSE_POINT,
7092 0, 0, /* in buffer */
7093 target_buffer, sizeof(target_buffer),
7094 &n_bytes_returned,
7095 0 /* we're not using OVERLAPPED_IO */
7096 );
7097 CloseHandle(reparse_point_handle);
7098 Py_END_ALLOW_THREADS
7099
7100 if (io_result==0)
7101 return win32_error_object("readlink", po);
7102
7103 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7104 {
7105 PyErr_SetString(PyExc_ValueError,
7106 "not a symbolic link");
7107 return NULL;
7108 }
7109 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7110 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7111
7112 result = PyUnicode_FromWideChar(print_name,
7113 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7114 return result;
7115}
7116
7117#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7118
7119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007120
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122
7123#if defined(MS_WINDOWS)
7124
7125/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007126static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007127
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007129check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130{
7131 HINSTANCE hKernel32;
7132 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007133 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134 return 1;
7135 hKernel32 = GetModuleHandleW(L"KERNEL32");
7136 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7137 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007138 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007139}
7140
Victor Stinner31b3b922013-06-05 01:49:17 +02007141/* Remove the last portion of the path */
7142static void
7143_dirnameW(WCHAR *path)
7144{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007145 WCHAR *ptr;
7146
7147 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007148 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007149 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007150 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007151 }
7152 *ptr = 0;
7153}
7154
Victor Stinner31b3b922013-06-05 01:49:17 +02007155/* Is this path absolute? */
7156static int
7157_is_absW(const WCHAR *path)
7158{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007159 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7160
7161}
7162
Victor Stinner31b3b922013-06-05 01:49:17 +02007163/* join root and rest with a backslash */
7164static void
7165_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7166{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007167 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007168
Victor Stinner31b3b922013-06-05 01:49:17 +02007169 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007170 wcscpy(dest_path, rest);
7171 return;
7172 }
7173
7174 root_len = wcslen(root);
7175
7176 wcscpy(dest_path, root);
7177 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007178 dest_path[root_len] = L'\\';
7179 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007180 }
7181 wcscpy(dest_path+root_len, rest);
7182}
7183
Victor Stinner31b3b922013-06-05 01:49:17 +02007184/* Return True if the path at src relative to dest is a directory */
7185static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007186_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007187{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007188 WIN32_FILE_ATTRIBUTE_DATA src_info;
7189 WCHAR dest_parent[MAX_PATH];
7190 WCHAR src_resolved[MAX_PATH] = L"";
7191
7192 /* dest_parent = os.path.dirname(dest) */
7193 wcscpy(dest_parent, dest);
7194 _dirnameW(dest_parent);
7195 /* src_resolved = os.path.join(dest_parent, src) */
7196 _joinW(src_resolved, dest_parent, src);
7197 return (
7198 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7199 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7200 );
7201}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007202#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007203
Larry Hastings2f936352014-08-05 14:04:04 +10007204
7205/*[clinic input]
7206os.symlink
7207 src: path_t
7208 dst: path_t
7209 target_is_directory: bool = False
7210 *
7211 dir_fd: dir_fd(requires='symlinkat')=None
7212
7213# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7214
7215Create a symbolic link pointing to src named dst.
7216
7217target_is_directory is required on Windows if the target is to be
7218 interpreted as a directory. (On Windows, symlink requires
7219 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7220 target_is_directory is ignored on non-Windows platforms.
7221
7222If dir_fd is not None, it should be a file descriptor open to a directory,
7223 and path should be relative; path will then be relative to that directory.
7224dir_fd may not be implemented on your platform.
7225 If it is unavailable, using it will raise a NotImplementedError.
7226
7227[clinic start generated code]*/
7228
Larry Hastings2f936352014-08-05 14:04:04 +10007229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007230os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007231 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007232/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007233{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007234#ifdef MS_WINDOWS
7235 DWORD result;
7236#else
7237 int result;
7238#endif
7239
Larry Hastings9cf065c2012-06-22 16:30:09 -07007240#ifdef MS_WINDOWS
7241 if (!check_CreateSymbolicLink()) {
7242 PyErr_SetString(PyExc_NotImplementedError,
7243 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007244 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007245 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007246 if (!win32_can_symlink) {
7247 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007248 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007249 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007250#endif
7251
Larry Hastings2f936352014-08-05 14:04:04 +10007252 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007253 PyErr_SetString(PyExc_ValueError,
7254 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007255 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007256 }
7257
7258#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007259
Larry Hastings9cf065c2012-06-22 16:30:09 -07007260 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007261 /* if src is a directory, ensure target_is_directory==1 */
7262 target_is_directory |= _check_dirW(src->wide, dst->wide);
7263 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7264 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265 Py_END_ALLOW_THREADS
7266
Larry Hastings2f936352014-08-05 14:04:04 +10007267 if (!result)
7268 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007269
7270#else
7271
7272 Py_BEGIN_ALLOW_THREADS
7273#if HAVE_SYMLINKAT
7274 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007275 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007276 else
7277#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007278 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007279 Py_END_ALLOW_THREADS
7280
Larry Hastings2f936352014-08-05 14:04:04 +10007281 if (result)
7282 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007283#endif
7284
Larry Hastings2f936352014-08-05 14:04:04 +10007285 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007286}
7287#endif /* HAVE_SYMLINK */
7288
Larry Hastings9cf065c2012-06-22 16:30:09 -07007289
Brian Curtind40e6f72010-07-08 21:39:08 +00007290
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007291
Larry Hastings605a62d2012-06-24 04:33:36 -07007292static PyStructSequence_Field times_result_fields[] = {
7293 {"user", "user time"},
7294 {"system", "system time"},
7295 {"children_user", "user time of children"},
7296 {"children_system", "system time of children"},
7297 {"elapsed", "elapsed time since an arbitrary point in the past"},
7298 {NULL}
7299};
7300
7301PyDoc_STRVAR(times_result__doc__,
7302"times_result: Result from os.times().\n\n\
7303This object may be accessed either as a tuple of\n\
7304 (user, system, children_user, children_system, elapsed),\n\
7305or via the attributes user, system, children_user, children_system,\n\
7306and elapsed.\n\
7307\n\
7308See os.times for more information.");
7309
7310static PyStructSequence_Desc times_result_desc = {
7311 "times_result", /* name */
7312 times_result__doc__, /* doc */
7313 times_result_fields,
7314 5
7315};
7316
7317static PyTypeObject TimesResultType;
7318
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007319#ifdef MS_WINDOWS
7320#define HAVE_TIMES /* mandatory, for the method table */
7321#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007322
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007323#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007324
7325static PyObject *
7326build_times_result(double user, double system,
7327 double children_user, double children_system,
7328 double elapsed)
7329{
7330 PyObject *value = PyStructSequence_New(&TimesResultType);
7331 if (value == NULL)
7332 return NULL;
7333
7334#define SET(i, field) \
7335 { \
7336 PyObject *o = PyFloat_FromDouble(field); \
7337 if (!o) { \
7338 Py_DECREF(value); \
7339 return NULL; \
7340 } \
7341 PyStructSequence_SET_ITEM(value, i, o); \
7342 } \
7343
7344 SET(0, user);
7345 SET(1, system);
7346 SET(2, children_user);
7347 SET(3, children_system);
7348 SET(4, elapsed);
7349
7350#undef SET
7351
7352 return value;
7353}
7354
Larry Hastings605a62d2012-06-24 04:33:36 -07007355
Larry Hastings2f936352014-08-05 14:04:04 +10007356#ifndef MS_WINDOWS
7357#define NEED_TICKS_PER_SECOND
7358static long ticks_per_second = -1;
7359#endif /* MS_WINDOWS */
7360
7361/*[clinic input]
7362os.times
7363
7364Return a collection containing process timing information.
7365
7366The object returned behaves like a named tuple with these fields:
7367 (utime, stime, cutime, cstime, elapsed_time)
7368All fields are floating point numbers.
7369[clinic start generated code]*/
7370
Larry Hastings2f936352014-08-05 14:04:04 +10007371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007372os_times_impl(PyObject *module)
7373/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007374#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007375{
Victor Stinner8c62be82010-05-06 00:08:46 +00007376 FILETIME create, exit, kernel, user;
7377 HANDLE hProc;
7378 hProc = GetCurrentProcess();
7379 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7380 /* The fields of a FILETIME structure are the hi and lo part
7381 of a 64-bit value expressed in 100 nanosecond units.
7382 1e7 is one second in such units; 1e-7 the inverse.
7383 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7384 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007385 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007386 (double)(user.dwHighDateTime*429.4967296 +
7387 user.dwLowDateTime*1e-7),
7388 (double)(kernel.dwHighDateTime*429.4967296 +
7389 kernel.dwLowDateTime*1e-7),
7390 (double)0,
7391 (double)0,
7392 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007393}
Larry Hastings2f936352014-08-05 14:04:04 +10007394#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007395{
Larry Hastings2f936352014-08-05 14:04:04 +10007396
7397
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007398 struct tms t;
7399 clock_t c;
7400 errno = 0;
7401 c = times(&t);
7402 if (c == (clock_t) -1)
7403 return posix_error();
7404 return build_times_result(
7405 (double)t.tms_utime / ticks_per_second,
7406 (double)t.tms_stime / ticks_per_second,
7407 (double)t.tms_cutime / ticks_per_second,
7408 (double)t.tms_cstime / ticks_per_second,
7409 (double)c / ticks_per_second);
7410}
Larry Hastings2f936352014-08-05 14:04:04 +10007411#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007412#endif /* HAVE_TIMES */
7413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007414
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007415#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007416/*[clinic input]
7417os.getsid
7418
7419 pid: pid_t
7420 /
7421
7422Call the system call getsid(pid) and return the result.
7423[clinic start generated code]*/
7424
Larry Hastings2f936352014-08-05 14:04:04 +10007425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007426os_getsid_impl(PyObject *module, pid_t pid)
7427/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007428{
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007430 sid = getsid(pid);
7431 if (sid < 0)
7432 return posix_error();
7433 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007434}
7435#endif /* HAVE_GETSID */
7436
7437
Guido van Rossumb6775db1994-08-01 11:34:53 +00007438#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007439/*[clinic input]
7440os.setsid
7441
7442Call the system call setsid().
7443[clinic start generated code]*/
7444
Larry Hastings2f936352014-08-05 14:04:04 +10007445static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007446os_setsid_impl(PyObject *module)
7447/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007448{
Victor Stinner8c62be82010-05-06 00:08:46 +00007449 if (setsid() < 0)
7450 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007451 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007452}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007453#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007454
Larry Hastings2f936352014-08-05 14:04:04 +10007455
Guido van Rossumb6775db1994-08-01 11:34:53 +00007456#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007457/*[clinic input]
7458os.setpgid
7459
7460 pid: pid_t
7461 pgrp: pid_t
7462 /
7463
7464Call the system call setpgid(pid, pgrp).
7465[clinic start generated code]*/
7466
Larry Hastings2f936352014-08-05 14:04:04 +10007467static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007468os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7469/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007470{
Victor Stinner8c62be82010-05-06 00:08:46 +00007471 if (setpgid(pid, pgrp) < 0)
7472 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007473 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007474}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007475#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007477
Guido van Rossumb6775db1994-08-01 11:34:53 +00007478#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007479/*[clinic input]
7480os.tcgetpgrp
7481
7482 fd: int
7483 /
7484
7485Return the process group associated with the terminal specified by fd.
7486[clinic start generated code]*/
7487
Larry Hastings2f936352014-08-05 14:04:04 +10007488static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007489os_tcgetpgrp_impl(PyObject *module, int fd)
7490/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007491{
7492 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007493 if (pgid < 0)
7494 return posix_error();
7495 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007496}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007497#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007499
Guido van Rossumb6775db1994-08-01 11:34:53 +00007500#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007501/*[clinic input]
7502os.tcsetpgrp
7503
7504 fd: int
7505 pgid: pid_t
7506 /
7507
7508Set the process group associated with the terminal specified by fd.
7509[clinic start generated code]*/
7510
Larry Hastings2f936352014-08-05 14:04:04 +10007511static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007512os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7513/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007514{
Victor Stinner8c62be82010-05-06 00:08:46 +00007515 if (tcsetpgrp(fd, pgid) < 0)
7516 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007517 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007518}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007519#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007520
Guido van Rossum687dd131993-05-17 08:34:16 +00007521/* Functions acting on file descriptors */
7522
Victor Stinnerdaf45552013-08-28 00:53:59 +02007523#ifdef O_CLOEXEC
7524extern int _Py_open_cloexec_works;
7525#endif
7526
Larry Hastings2f936352014-08-05 14:04:04 +10007527
7528/*[clinic input]
7529os.open -> int
7530 path: path_t
7531 flags: int
7532 mode: int = 0o777
7533 *
7534 dir_fd: dir_fd(requires='openat') = None
7535
7536# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7537
7538Open a file for low level IO. Returns a file descriptor (integer).
7539
7540If dir_fd is not None, it should be a file descriptor open to a directory,
7541 and path should be relative; path will then be relative to that directory.
7542dir_fd may not be implemented on your platform.
7543 If it is unavailable, using it will raise a NotImplementedError.
7544[clinic start generated code]*/
7545
Larry Hastings2f936352014-08-05 14:04:04 +10007546static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007547os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7548/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007549{
7550 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007551 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007552
Victor Stinnerdaf45552013-08-28 00:53:59 +02007553#ifdef O_CLOEXEC
7554 int *atomic_flag_works = &_Py_open_cloexec_works;
7555#elif !defined(MS_WINDOWS)
7556 int *atomic_flag_works = NULL;
7557#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007558
Victor Stinnerdaf45552013-08-28 00:53:59 +02007559#ifdef MS_WINDOWS
7560 flags |= O_NOINHERIT;
7561#elif defined(O_CLOEXEC)
7562 flags |= O_CLOEXEC;
7563#endif
7564
Steve Dower8fc89802015-04-12 00:26:27 -04007565 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007566 do {
7567 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007568#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007569 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007570#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007571#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007572 if (dir_fd != DEFAULT_DIR_FD)
7573 fd = openat(dir_fd, path->narrow, flags, mode);
7574 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007575#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007576 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007577#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007578 Py_END_ALLOW_THREADS
7579 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007580 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007581
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007582 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007583 if (!async_err)
7584 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007585 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007586 }
7587
Victor Stinnerdaf45552013-08-28 00:53:59 +02007588#ifndef MS_WINDOWS
7589 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7590 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007591 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007592 }
7593#endif
7594
Larry Hastings2f936352014-08-05 14:04:04 +10007595 return fd;
7596}
7597
7598
7599/*[clinic input]
7600os.close
7601
7602 fd: int
7603
7604Close a file descriptor.
7605[clinic start generated code]*/
7606
Barry Warsaw53699e91996-12-10 23:23:01 +00007607static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007608os_close_impl(PyObject *module, int fd)
7609/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007610{
Larry Hastings2f936352014-08-05 14:04:04 +10007611 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007612 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7613 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7614 * for more details.
7615 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007617 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007619 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 Py_END_ALLOW_THREADS
7621 if (res < 0)
7622 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007623 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007624}
7625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007626
Larry Hastings2f936352014-08-05 14:04:04 +10007627/*[clinic input]
7628os.closerange
7629
7630 fd_low: int
7631 fd_high: int
7632 /
7633
7634Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7635[clinic start generated code]*/
7636
Larry Hastings2f936352014-08-05 14:04:04 +10007637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007638os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7639/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007640{
7641 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007643 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007644 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007645 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007646 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007647 Py_END_ALLOW_THREADS
7648 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007649}
7650
7651
Larry Hastings2f936352014-08-05 14:04:04 +10007652/*[clinic input]
7653os.dup -> int
7654
7655 fd: int
7656 /
7657
7658Return a duplicate of a file descriptor.
7659[clinic start generated code]*/
7660
Larry Hastings2f936352014-08-05 14:04:04 +10007661static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007662os_dup_impl(PyObject *module, int fd)
7663/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007664{
7665 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007666}
7667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007668
Larry Hastings2f936352014-08-05 14:04:04 +10007669/*[clinic input]
7670os.dup2
7671 fd: int
7672 fd2: int
7673 inheritable: bool=True
7674
7675Duplicate file descriptor.
7676[clinic start generated code]*/
7677
Larry Hastings2f936352014-08-05 14:04:04 +10007678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007679os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7680/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007681{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007682 int res;
7683#if defined(HAVE_DUP3) && \
7684 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7685 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7686 int dup3_works = -1;
7687#endif
7688
Steve Dower940f33a2016-09-08 11:21:54 -07007689 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007691
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007692 /* dup2() can fail with EINTR if the target FD is already open, because it
7693 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7694 * upon close(), and therefore below.
7695 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007696#ifdef MS_WINDOWS
7697 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007698 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007699 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007700 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007701 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 if (res < 0)
7703 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007704
7705 /* Character files like console cannot be make non-inheritable */
7706 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7707 close(fd2);
7708 return NULL;
7709 }
7710
7711#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7712 Py_BEGIN_ALLOW_THREADS
7713 if (!inheritable)
7714 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7715 else
7716 res = dup2(fd, fd2);
7717 Py_END_ALLOW_THREADS
7718 if (res < 0)
7719 return posix_error();
7720
7721#else
7722
7723#ifdef HAVE_DUP3
7724 if (!inheritable && dup3_works != 0) {
7725 Py_BEGIN_ALLOW_THREADS
7726 res = dup3(fd, fd2, O_CLOEXEC);
7727 Py_END_ALLOW_THREADS
7728 if (res < 0) {
7729 if (dup3_works == -1)
7730 dup3_works = (errno != ENOSYS);
7731 if (dup3_works)
7732 return posix_error();
7733 }
7734 }
7735
7736 if (inheritable || dup3_works == 0)
7737 {
7738#endif
7739 Py_BEGIN_ALLOW_THREADS
7740 res = dup2(fd, fd2);
7741 Py_END_ALLOW_THREADS
7742 if (res < 0)
7743 return posix_error();
7744
7745 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7746 close(fd2);
7747 return NULL;
7748 }
7749#ifdef HAVE_DUP3
7750 }
7751#endif
7752
7753#endif
7754
Larry Hastings2f936352014-08-05 14:04:04 +10007755 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007756}
7757
Larry Hastings2f936352014-08-05 14:04:04 +10007758
Ross Lagerwall7807c352011-03-17 20:20:30 +02007759#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007760/*[clinic input]
7761os.lockf
7762
7763 fd: int
7764 An open file descriptor.
7765 command: int
7766 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7767 length: Py_off_t
7768 The number of bytes to lock, starting at the current position.
7769 /
7770
7771Apply, test or remove a POSIX lock on an open file descriptor.
7772
7773[clinic start generated code]*/
7774
Larry Hastings2f936352014-08-05 14:04:04 +10007775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007776os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7777/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007778{
7779 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007780
7781 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007782 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007783 Py_END_ALLOW_THREADS
7784
7785 if (res < 0)
7786 return posix_error();
7787
7788 Py_RETURN_NONE;
7789}
Larry Hastings2f936352014-08-05 14:04:04 +10007790#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007792
Larry Hastings2f936352014-08-05 14:04:04 +10007793/*[clinic input]
7794os.lseek -> Py_off_t
7795
7796 fd: int
7797 position: Py_off_t
7798 how: int
7799 /
7800
7801Set the position of a file descriptor. Return the new position.
7802
7803Return the new cursor position in number of bytes
7804relative to the beginning of the file.
7805[clinic start generated code]*/
7806
Larry Hastings2f936352014-08-05 14:04:04 +10007807static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007808os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7809/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007810{
7811 Py_off_t result;
7812
Guido van Rossum687dd131993-05-17 08:34:16 +00007813#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7815 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007816 case 0: how = SEEK_SET; break;
7817 case 1: how = SEEK_CUR; break;
7818 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007820#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007821
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007823 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007824
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007826 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007827#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007828 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007829#else
Larry Hastings2f936352014-08-05 14:04:04 +10007830 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007831#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007832 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007834 if (result < 0)
7835 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007836
Larry Hastings2f936352014-08-05 14:04:04 +10007837 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007838}
7839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007840
Larry Hastings2f936352014-08-05 14:04:04 +10007841/*[clinic input]
7842os.read
7843 fd: int
7844 length: Py_ssize_t
7845 /
7846
7847Read from a file descriptor. Returns a bytes object.
7848[clinic start generated code]*/
7849
Larry Hastings2f936352014-08-05 14:04:04 +10007850static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007851os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7852/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007853{
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 Py_ssize_t n;
7855 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007856
7857 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 errno = EINVAL;
7859 return posix_error();
7860 }
Larry Hastings2f936352014-08-05 14:04:04 +10007861
7862#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007863 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007864 if (length > INT_MAX)
7865 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007866#endif
7867
7868 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 if (buffer == NULL)
7870 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007871
Victor Stinner66aab0c2015-03-19 22:53:20 +01007872 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7873 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007875 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 }
Larry Hastings2f936352014-08-05 14:04:04 +10007877
7878 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007880
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007882}
7883
Ross Lagerwall7807c352011-03-17 20:20:30 +02007884#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7885 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007886static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007887iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7888{
7889 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007890 Py_ssize_t blen, total = 0;
7891
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007892 *iov = PyMem_New(struct iovec, cnt);
7893 if (*iov == NULL) {
7894 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007895 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007896 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007897
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007898 *buf = PyMem_New(Py_buffer, cnt);
7899 if (*buf == NULL) {
7900 PyMem_Del(*iov);
7901 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007902 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007903 }
7904
7905 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007906 PyObject *item = PySequence_GetItem(seq, i);
7907 if (item == NULL)
7908 goto fail;
7909 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7910 Py_DECREF(item);
7911 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007912 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007913 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007914 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007915 blen = (*buf)[i].len;
7916 (*iov)[i].iov_len = blen;
7917 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007918 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007919 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007920
7921fail:
7922 PyMem_Del(*iov);
7923 for (j = 0; j < i; j++) {
7924 PyBuffer_Release(&(*buf)[j]);
7925 }
7926 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007927 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007928}
7929
7930static void
7931iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7932{
7933 int i;
7934 PyMem_Del(iov);
7935 for (i = 0; i < cnt; i++) {
7936 PyBuffer_Release(&buf[i]);
7937 }
7938 PyMem_Del(buf);
7939}
7940#endif
7941
Larry Hastings2f936352014-08-05 14:04:04 +10007942
Ross Lagerwall7807c352011-03-17 20:20:30 +02007943#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007944/*[clinic input]
7945os.readv -> Py_ssize_t
7946
7947 fd: int
7948 buffers: object
7949 /
7950
7951Read from a file descriptor fd into an iterable of buffers.
7952
7953The buffers should be mutable buffers accepting bytes.
7954readv will transfer data into each buffer until it is full
7955and then move on to the next buffer in the sequence to hold
7956the rest of the data.
7957
7958readv returns the total number of bytes read,
7959which may be less than the total capacity of all the buffers.
7960[clinic start generated code]*/
7961
Larry Hastings2f936352014-08-05 14:04:04 +10007962static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007963os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7964/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007965{
7966 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007967 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007968 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007969 struct iovec *iov;
7970 Py_buffer *buf;
7971
Larry Hastings2f936352014-08-05 14:04:04 +10007972 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007973 PyErr_SetString(PyExc_TypeError,
7974 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007975 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007976 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007977
Larry Hastings2f936352014-08-05 14:04:04 +10007978 cnt = PySequence_Size(buffers);
7979
7980 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7981 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007982
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007983 do {
7984 Py_BEGIN_ALLOW_THREADS
7985 n = readv(fd, iov, cnt);
7986 Py_END_ALLOW_THREADS
7987 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007988
7989 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007990 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007991 if (!async_err)
7992 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007993 return -1;
7994 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007995
Larry Hastings2f936352014-08-05 14:04:04 +10007996 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007997}
Larry Hastings2f936352014-08-05 14:04:04 +10007998#endif /* HAVE_READV */
7999
Ross Lagerwall7807c352011-03-17 20:20:30 +02008000
8001#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008002/*[clinic input]
8003# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8004os.pread
8005
8006 fd: int
8007 length: int
8008 offset: Py_off_t
8009 /
8010
8011Read a number of bytes from a file descriptor starting at a particular offset.
8012
8013Read length bytes from file descriptor fd, starting at offset bytes from
8014the beginning of the file. The file offset remains unchanged.
8015[clinic start generated code]*/
8016
Larry Hastings2f936352014-08-05 14:04:04 +10008017static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008018os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8019/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008020{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008021 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008022 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008024
Larry Hastings2f936352014-08-05 14:04:04 +10008025 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008026 errno = EINVAL;
8027 return posix_error();
8028 }
Larry Hastings2f936352014-08-05 14:04:04 +10008029 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008030 if (buffer == NULL)
8031 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008032
8033 do {
8034 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008035 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008036 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008037 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008038 Py_END_ALLOW_THREADS
8039 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8040
Ross Lagerwall7807c352011-03-17 20:20:30 +02008041 if (n < 0) {
8042 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008043 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008044 }
Larry Hastings2f936352014-08-05 14:04:04 +10008045 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008046 _PyBytes_Resize(&buffer, n);
8047 return buffer;
8048}
Larry Hastings2f936352014-08-05 14:04:04 +10008049#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008050
Larry Hastings2f936352014-08-05 14:04:04 +10008051
8052/*[clinic input]
8053os.write -> Py_ssize_t
8054
8055 fd: int
8056 data: Py_buffer
8057 /
8058
8059Write a bytes object to a file descriptor.
8060[clinic start generated code]*/
8061
Larry Hastings2f936352014-08-05 14:04:04 +10008062static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008063os_write_impl(PyObject *module, int fd, Py_buffer *data)
8064/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008065{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008066 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008067}
8068
8069#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008071"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008072sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008073 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008074Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075
Larry Hastings2f936352014-08-05 14:04:04 +10008076/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077static PyObject *
8078posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8079{
8080 int in, out;
8081 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008082 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008083 off_t offset;
8084
8085#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8086#ifndef __APPLE__
8087 Py_ssize_t len;
8088#endif
8089 PyObject *headers = NULL, *trailers = NULL;
8090 Py_buffer *hbuf, *tbuf;
8091 off_t sbytes;
8092 struct sf_hdtr sf;
8093 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008094 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008095 static char *keywords[] = {"out", "in",
8096 "offset", "count",
8097 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008098
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008099 sf.headers = NULL;
8100 sf.trailers = NULL;
8101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008102#ifdef __APPLE__
8103 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008104 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008105#else
8106 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008107 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008108#endif
8109 &headers, &trailers, &flags))
8110 return NULL;
8111 if (headers != NULL) {
8112 if (!PySequence_Check(headers)) {
8113 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008114 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008115 return NULL;
8116 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008117 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008118 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008119 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008120 (i = iov_setup(&(sf.headers), &hbuf,
8121 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008122 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008123#ifdef __APPLE__
8124 sbytes += i;
8125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008126 }
8127 }
8128 if (trailers != NULL) {
8129 if (!PySequence_Check(trailers)) {
8130 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008131 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008132 return NULL;
8133 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008134 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008135 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008136 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008137 (i = iov_setup(&(sf.trailers), &tbuf,
8138 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008139 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008140#ifdef __APPLE__
8141 sbytes += i;
8142#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008143 }
8144 }
8145
Steve Dower8fc89802015-04-12 00:26:27 -04008146 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008147 do {
8148 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008149#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008150 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008151#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008152 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008153#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008154 Py_END_ALLOW_THREADS
8155 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008156 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008157
8158 if (sf.headers != NULL)
8159 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8160 if (sf.trailers != NULL)
8161 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8162
8163 if (ret < 0) {
8164 if ((errno == EAGAIN) || (errno == EBUSY)) {
8165 if (sbytes != 0) {
8166 // some data has been sent
8167 goto done;
8168 }
8169 else {
8170 // no data has been sent; upper application is supposed
8171 // to retry on EAGAIN or EBUSY
8172 return posix_error();
8173 }
8174 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008175 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008176 }
8177 goto done;
8178
8179done:
8180 #if !defined(HAVE_LARGEFILE_SUPPORT)
8181 return Py_BuildValue("l", sbytes);
8182 #else
8183 return Py_BuildValue("L", sbytes);
8184 #endif
8185
8186#else
8187 Py_ssize_t count;
8188 PyObject *offobj;
8189 static char *keywords[] = {"out", "in",
8190 "offset", "count", NULL};
8191 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8192 keywords, &out, &in, &offobj, &count))
8193 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008194#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008195 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008196 do {
8197 Py_BEGIN_ALLOW_THREADS
8198 ret = sendfile(out, in, NULL, count);
8199 Py_END_ALLOW_THREADS
8200 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008201 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008202 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008203 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008204 }
8205#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008206 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008207 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008208
8209 do {
8210 Py_BEGIN_ALLOW_THREADS
8211 ret = sendfile(out, in, &offset, count);
8212 Py_END_ALLOW_THREADS
8213 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008214 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008215 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008216 return Py_BuildValue("n", ret);
8217#endif
8218}
Larry Hastings2f936352014-08-05 14:04:04 +10008219#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008220
Larry Hastings2f936352014-08-05 14:04:04 +10008221
8222/*[clinic input]
8223os.fstat
8224
8225 fd : int
8226
8227Perform a stat system call on the given file descriptor.
8228
8229Like stat(), but for an open file descriptor.
8230Equivalent to os.stat(fd).
8231[clinic start generated code]*/
8232
Larry Hastings2f936352014-08-05 14:04:04 +10008233static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008234os_fstat_impl(PyObject *module, int fd)
8235/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008236{
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 STRUCT_STAT st;
8238 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008239 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008240
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008241 do {
8242 Py_BEGIN_ALLOW_THREADS
8243 res = FSTAT(fd, &st);
8244 Py_END_ALLOW_THREADS
8245 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008246 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008247#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008248 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008249#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008250 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008251#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 }
Tim Peters5aa91602002-01-30 05:46:57 +00008253
Victor Stinner4195b5c2012-02-08 23:03:19 +01008254 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008255}
8256
Larry Hastings2f936352014-08-05 14:04:04 +10008257
8258/*[clinic input]
8259os.isatty -> bool
8260 fd: int
8261 /
8262
8263Return True if the fd is connected to a terminal.
8264
8265Return True if the file descriptor is an open file descriptor
8266connected to the slave end of a terminal.
8267[clinic start generated code]*/
8268
Larry Hastings2f936352014-08-05 14:04:04 +10008269static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008270os_isatty_impl(PyObject *module, int fd)
8271/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008272{
Steve Dower8fc89802015-04-12 00:26:27 -04008273 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008274 _Py_BEGIN_SUPPRESS_IPH
8275 return_value = isatty(fd);
8276 _Py_END_SUPPRESS_IPH
8277 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008278}
8279
8280
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008281#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008282/*[clinic input]
8283os.pipe
8284
8285Create a pipe.
8286
8287Returns a tuple of two file descriptors:
8288 (read_fd, write_fd)
8289[clinic start generated code]*/
8290
Larry Hastings2f936352014-08-05 14:04:04 +10008291static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008292os_pipe_impl(PyObject *module)
8293/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008294{
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008296#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008298 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008300#else
8301 int res;
8302#endif
8303
8304#ifdef MS_WINDOWS
8305 attr.nLength = sizeof(attr);
8306 attr.lpSecurityDescriptor = NULL;
8307 attr.bInheritHandle = FALSE;
8308
8309 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008310 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008311 ok = CreatePipe(&read, &write, &attr, 0);
8312 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008313 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8314 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008315 if (fds[0] == -1 || fds[1] == -1) {
8316 CloseHandle(read);
8317 CloseHandle(write);
8318 ok = 0;
8319 }
8320 }
Steve Dowerc3630612016-11-19 18:41:16 -08008321 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008322 Py_END_ALLOW_THREADS
8323
Victor Stinner8c62be82010-05-06 00:08:46 +00008324 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008325 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008326#else
8327
8328#ifdef HAVE_PIPE2
8329 Py_BEGIN_ALLOW_THREADS
8330 res = pipe2(fds, O_CLOEXEC);
8331 Py_END_ALLOW_THREADS
8332
8333 if (res != 0 && errno == ENOSYS)
8334 {
8335#endif
8336 Py_BEGIN_ALLOW_THREADS
8337 res = pipe(fds);
8338 Py_END_ALLOW_THREADS
8339
8340 if (res == 0) {
8341 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8342 close(fds[0]);
8343 close(fds[1]);
8344 return NULL;
8345 }
8346 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8347 close(fds[0]);
8348 close(fds[1]);
8349 return NULL;
8350 }
8351 }
8352#ifdef HAVE_PIPE2
8353 }
8354#endif
8355
8356 if (res != 0)
8357 return PyErr_SetFromErrno(PyExc_OSError);
8358#endif /* !MS_WINDOWS */
8359 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008360}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008361#endif /* HAVE_PIPE */
8362
Larry Hastings2f936352014-08-05 14:04:04 +10008363
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008364#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008365/*[clinic input]
8366os.pipe2
8367
8368 flags: int
8369 /
8370
8371Create a pipe with flags set atomically.
8372
8373Returns a tuple of two file descriptors:
8374 (read_fd, write_fd)
8375
8376flags can be constructed by ORing together one or more of these values:
8377O_NONBLOCK, O_CLOEXEC.
8378[clinic start generated code]*/
8379
Larry Hastings2f936352014-08-05 14:04:04 +10008380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008381os_pipe2_impl(PyObject *module, int flags)
8382/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008383{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008384 int fds[2];
8385 int res;
8386
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008387 res = pipe2(fds, flags);
8388 if (res != 0)
8389 return posix_error();
8390 return Py_BuildValue("(ii)", fds[0], fds[1]);
8391}
8392#endif /* HAVE_PIPE2 */
8393
Larry Hastings2f936352014-08-05 14:04:04 +10008394
Ross Lagerwall7807c352011-03-17 20:20:30 +02008395#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008396/*[clinic input]
8397os.writev -> Py_ssize_t
8398 fd: int
8399 buffers: object
8400 /
8401
8402Iterate over buffers, and write the contents of each to a file descriptor.
8403
8404Returns the total number of bytes written.
8405buffers must be a sequence of bytes-like objects.
8406[clinic start generated code]*/
8407
Larry Hastings2f936352014-08-05 14:04:04 +10008408static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008409os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8410/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008411{
8412 int cnt;
8413 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008414 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008415 struct iovec *iov;
8416 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008417
8418 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008419 PyErr_SetString(PyExc_TypeError,
8420 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008421 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008422 }
Larry Hastings2f936352014-08-05 14:04:04 +10008423 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008424
Larry Hastings2f936352014-08-05 14:04:04 +10008425 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8426 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008427 }
8428
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008429 do {
8430 Py_BEGIN_ALLOW_THREADS
8431 result = writev(fd, iov, cnt);
8432 Py_END_ALLOW_THREADS
8433 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008434
8435 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008436 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008437 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008438
Georg Brandl306336b2012-06-24 12:55:33 +02008439 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008440}
Larry Hastings2f936352014-08-05 14:04:04 +10008441#endif /* HAVE_WRITEV */
8442
8443
8444#ifdef HAVE_PWRITE
8445/*[clinic input]
8446os.pwrite -> Py_ssize_t
8447
8448 fd: int
8449 buffer: Py_buffer
8450 offset: Py_off_t
8451 /
8452
8453Write bytes to a file descriptor starting at a particular offset.
8454
8455Write buffer to fd, starting at offset bytes from the beginning of
8456the file. Returns the number of bytes writte. Does not change the
8457current file offset.
8458[clinic start generated code]*/
8459
Larry Hastings2f936352014-08-05 14:04:04 +10008460static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008461os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8462/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008463{
8464 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008465 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008466
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008467 do {
8468 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008469 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008470 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008471 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008472 Py_END_ALLOW_THREADS
8473 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008474
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008475 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008476 posix_error();
8477 return size;
8478}
8479#endif /* HAVE_PWRITE */
8480
8481
8482#ifdef HAVE_MKFIFO
8483/*[clinic input]
8484os.mkfifo
8485
8486 path: path_t
8487 mode: int=0o666
8488 *
8489 dir_fd: dir_fd(requires='mkfifoat')=None
8490
8491Create a "fifo" (a POSIX named pipe).
8492
8493If dir_fd is not None, it should be a file descriptor open to a directory,
8494 and path should be relative; path will then be relative to that directory.
8495dir_fd may not be implemented on your platform.
8496 If it is unavailable, using it will raise a NotImplementedError.
8497[clinic start generated code]*/
8498
Larry Hastings2f936352014-08-05 14:04:04 +10008499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008500os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8501/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008502{
8503 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008504 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008505
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008506 do {
8507 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008508#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008509 if (dir_fd != DEFAULT_DIR_FD)
8510 result = mkfifoat(dir_fd, path->narrow, mode);
8511 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008512#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008513 result = mkfifo(path->narrow, mode);
8514 Py_END_ALLOW_THREADS
8515 } while (result != 0 && errno == EINTR &&
8516 !(async_err = PyErr_CheckSignals()));
8517 if (result != 0)
8518 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008519
8520 Py_RETURN_NONE;
8521}
8522#endif /* HAVE_MKFIFO */
8523
8524
8525#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8526/*[clinic input]
8527os.mknod
8528
8529 path: path_t
8530 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008531 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008532 *
8533 dir_fd: dir_fd(requires='mknodat')=None
8534
8535Create a node in the file system.
8536
8537Create a node in the file system (file, device special file or named pipe)
8538at path. mode specifies both the permissions to use and the
8539type of node to be created, being combined (bitwise OR) with one of
8540S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8541device defines the newly created device special file (probably using
8542os.makedev()). Otherwise device is ignored.
8543
8544If dir_fd is not None, it should be a file descriptor open to a directory,
8545 and path should be relative; path will then be relative to that directory.
8546dir_fd may not be implemented on your platform.
8547 If it is unavailable, using it will raise a NotImplementedError.
8548[clinic start generated code]*/
8549
Larry Hastings2f936352014-08-05 14:04:04 +10008550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008551os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008552 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008553/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008554{
8555 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008556 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008557
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008558 do {
8559 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008560#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008561 if (dir_fd != DEFAULT_DIR_FD)
8562 result = mknodat(dir_fd, path->narrow, mode, device);
8563 else
Larry Hastings2f936352014-08-05 14:04:04 +10008564#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008565 result = mknod(path->narrow, mode, device);
8566 Py_END_ALLOW_THREADS
8567 } while (result != 0 && errno == EINTR &&
8568 !(async_err = PyErr_CheckSignals()));
8569 if (result != 0)
8570 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008571
8572 Py_RETURN_NONE;
8573}
8574#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8575
8576
8577#ifdef HAVE_DEVICE_MACROS
8578/*[clinic input]
8579os.major -> unsigned_int
8580
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008581 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008582 /
8583
8584Extracts a device major number from a raw device number.
8585[clinic start generated code]*/
8586
Larry Hastings2f936352014-08-05 14:04:04 +10008587static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008588os_major_impl(PyObject *module, dev_t device)
8589/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008590{
8591 return major(device);
8592}
8593
8594
8595/*[clinic input]
8596os.minor -> unsigned_int
8597
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008598 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008599 /
8600
8601Extracts a device minor number from a raw device number.
8602[clinic start generated code]*/
8603
Larry Hastings2f936352014-08-05 14:04:04 +10008604static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008605os_minor_impl(PyObject *module, dev_t device)
8606/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008607{
8608 return minor(device);
8609}
8610
8611
8612/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008613os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008614
8615 major: int
8616 minor: int
8617 /
8618
8619Composes a raw device number from the major and minor device numbers.
8620[clinic start generated code]*/
8621
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008622static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008623os_makedev_impl(PyObject *module, int major, int minor)
8624/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008625{
8626 return makedev(major, minor);
8627}
8628#endif /* HAVE_DEVICE_MACROS */
8629
8630
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008631#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008632/*[clinic input]
8633os.ftruncate
8634
8635 fd: int
8636 length: Py_off_t
8637 /
8638
8639Truncate a file, specified by file descriptor, to a specific length.
8640[clinic start generated code]*/
8641
Larry Hastings2f936352014-08-05 14:04:04 +10008642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008643os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8644/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008645{
8646 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008647 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008648
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008649 do {
8650 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008651 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008652#ifdef MS_WINDOWS
8653 result = _chsize_s(fd, length);
8654#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008655 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008656#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008657 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008658 Py_END_ALLOW_THREADS
8659 } while (result != 0 && errno == EINTR &&
8660 !(async_err = PyErr_CheckSignals()));
8661 if (result != 0)
8662 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008663 Py_RETURN_NONE;
8664}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008665#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008666
8667
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008668#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008669/*[clinic input]
8670os.truncate
8671 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8672 length: Py_off_t
8673
8674Truncate a file, specified by path, to a specific length.
8675
8676On some platforms, path may also be specified as an open file descriptor.
8677 If this functionality is unavailable, using it raises an exception.
8678[clinic start generated code]*/
8679
Larry Hastings2f936352014-08-05 14:04:04 +10008680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008681os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8682/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008683{
8684 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008685#ifdef MS_WINDOWS
8686 int fd;
8687#endif
8688
8689 if (path->fd != -1)
8690 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008691
8692 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008693 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008694#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008695 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008696 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008697 result = -1;
8698 else {
8699 result = _chsize_s(fd, length);
8700 close(fd);
8701 if (result < 0)
8702 errno = result;
8703 }
8704#else
8705 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008706#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008707 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008708 Py_END_ALLOW_THREADS
8709 if (result < 0)
8710 return path_error(path);
8711
8712 Py_RETURN_NONE;
8713}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008714#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008715
Ross Lagerwall7807c352011-03-17 20:20:30 +02008716
Victor Stinnerd6b17692014-09-30 12:20:05 +02008717/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8718 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8719 defined, which is the case in Python on AIX. AIX bug report:
8720 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8721#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8722# define POSIX_FADVISE_AIX_BUG
8723#endif
8724
Victor Stinnerec39e262014-09-30 12:35:58 +02008725
Victor Stinnerd6b17692014-09-30 12:20:05 +02008726#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008727/*[clinic input]
8728os.posix_fallocate
8729
8730 fd: int
8731 offset: Py_off_t
8732 length: Py_off_t
8733 /
8734
8735Ensure a file has allocated at least a particular number of bytes on disk.
8736
8737Ensure that the file specified by fd encompasses a range of bytes
8738starting at offset bytes from the beginning and continuing for length bytes.
8739[clinic start generated code]*/
8740
Larry Hastings2f936352014-08-05 14:04:04 +10008741static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008742os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008743 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008744/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008745{
8746 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008747 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008748
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008749 do {
8750 Py_BEGIN_ALLOW_THREADS
8751 result = posix_fallocate(fd, offset, length);
8752 Py_END_ALLOW_THREADS
8753 } while (result != 0 && errno == EINTR &&
8754 !(async_err = PyErr_CheckSignals()));
8755 if (result != 0)
8756 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008757 Py_RETURN_NONE;
8758}
Victor Stinnerec39e262014-09-30 12:35:58 +02008759#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008760
Ross Lagerwall7807c352011-03-17 20:20:30 +02008761
Victor Stinnerd6b17692014-09-30 12:20:05 +02008762#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008763/*[clinic input]
8764os.posix_fadvise
8765
8766 fd: int
8767 offset: Py_off_t
8768 length: Py_off_t
8769 advice: int
8770 /
8771
8772Announce an intention to access data in a specific pattern.
8773
8774Announce an intention to access data in a specific pattern, thus allowing
8775the kernel to make optimizations.
8776The advice applies to the region of the file specified by fd starting at
8777offset and continuing for length bytes.
8778advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8779POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8780POSIX_FADV_DONTNEED.
8781[clinic start generated code]*/
8782
Larry Hastings2f936352014-08-05 14:04:04 +10008783static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008784os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008785 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008786/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008787{
8788 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008789 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008790
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008791 do {
8792 Py_BEGIN_ALLOW_THREADS
8793 result = posix_fadvise(fd, offset, length, advice);
8794 Py_END_ALLOW_THREADS
8795 } while (result != 0 && errno == EINTR &&
8796 !(async_err = PyErr_CheckSignals()));
8797 if (result != 0)
8798 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008799 Py_RETURN_NONE;
8800}
Victor Stinnerec39e262014-09-30 12:35:58 +02008801#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008802
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008803#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008804
Fred Drake762e2061999-08-26 17:23:54 +00008805/* Save putenv() parameters as values here, so we can collect them when they
8806 * get re-set with another call for the same key. */
8807static PyObject *posix_putenv_garbage;
8808
Larry Hastings2f936352014-08-05 14:04:04 +10008809static void
8810posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008811{
Larry Hastings2f936352014-08-05 14:04:04 +10008812 /* Install the first arg and newstr in posix_putenv_garbage;
8813 * this will cause previous value to be collected. This has to
8814 * happen after the real putenv() call because the old value
8815 * was still accessible until then. */
8816 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8817 /* really not much we can do; just leak */
8818 PyErr_Clear();
8819 else
8820 Py_DECREF(value);
8821}
8822
8823
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008824#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008825/*[clinic input]
8826os.putenv
8827
8828 name: unicode
8829 value: unicode
8830 /
8831
8832Change or add an environment variable.
8833[clinic start generated code]*/
8834
Larry Hastings2f936352014-08-05 14:04:04 +10008835static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008836os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8837/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008838{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008839 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008840
8841 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8842 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008843 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008844 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008845 }
Larry Hastings2f936352014-08-05 14:04:04 +10008846 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008847 PyErr_Format(PyExc_ValueError,
8848 "the environment variable is longer than %u characters",
8849 _MAX_ENV);
8850 goto error;
8851 }
8852
Larry Hastings2f936352014-08-05 14:04:04 +10008853 env = PyUnicode_AsUnicode(unicode);
8854 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008855 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008856 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008857 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008858 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008860
Larry Hastings2f936352014-08-05 14:04:04 +10008861 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008862 Py_RETURN_NONE;
8863
8864error:
Larry Hastings2f936352014-08-05 14:04:04 +10008865 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008866 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008867}
Larry Hastings2f936352014-08-05 14:04:04 +10008868#else /* MS_WINDOWS */
8869/*[clinic input]
8870os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008871
Larry Hastings2f936352014-08-05 14:04:04 +10008872 name: FSConverter
8873 value: FSConverter
8874 /
8875
8876Change or add an environment variable.
8877[clinic start generated code]*/
8878
Larry Hastings2f936352014-08-05 14:04:04 +10008879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008880os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8881/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008882{
8883 PyObject *bytes = NULL;
8884 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008885 const char *name_string = PyBytes_AsString(name);
8886 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008887
8888 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8889 if (bytes == NULL) {
8890 PyErr_NoMemory();
8891 return NULL;
8892 }
8893
8894 env = PyBytes_AS_STRING(bytes);
8895 if (putenv(env)) {
8896 Py_DECREF(bytes);
8897 return posix_error();
8898 }
8899
8900 posix_putenv_garbage_setitem(name, bytes);
8901 Py_RETURN_NONE;
8902}
8903#endif /* MS_WINDOWS */
8904#endif /* HAVE_PUTENV */
8905
8906
8907#ifdef HAVE_UNSETENV
8908/*[clinic input]
8909os.unsetenv
8910 name: FSConverter
8911 /
8912
8913Delete an environment variable.
8914[clinic start generated code]*/
8915
Larry Hastings2f936352014-08-05 14:04:04 +10008916static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008917os_unsetenv_impl(PyObject *module, PyObject *name)
8918/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008919{
Victor Stinner984890f2011-11-24 13:53:38 +01008920#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008921 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008922#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008923
Victor Stinner984890f2011-11-24 13:53:38 +01008924#ifdef HAVE_BROKEN_UNSETENV
8925 unsetenv(PyBytes_AS_STRING(name));
8926#else
Victor Stinner65170952011-11-22 22:16:17 +01008927 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008928 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008929 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008930#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008931
Victor Stinner8c62be82010-05-06 00:08:46 +00008932 /* Remove the key from posix_putenv_garbage;
8933 * this will cause it to be collected. This has to
8934 * happen after the real unsetenv() call because the
8935 * old value was still accessible until then.
8936 */
Victor Stinner65170952011-11-22 22:16:17 +01008937 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 /* really not much we can do; just leak */
8939 PyErr_Clear();
8940 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008941 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008942}
Larry Hastings2f936352014-08-05 14:04:04 +10008943#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008944
Larry Hastings2f936352014-08-05 14:04:04 +10008945
8946/*[clinic input]
8947os.strerror
8948
8949 code: int
8950 /
8951
8952Translate an error code to a message string.
8953[clinic start generated code]*/
8954
Larry Hastings2f936352014-08-05 14:04:04 +10008955static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008956os_strerror_impl(PyObject *module, int code)
8957/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008958{
8959 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 if (message == NULL) {
8961 PyErr_SetString(PyExc_ValueError,
8962 "strerror() argument out of range");
8963 return NULL;
8964 }
Victor Stinner1b579672011-12-17 05:47:23 +01008965 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008966}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008967
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008968
Guido van Rossumc9641791998-08-04 15:26:23 +00008969#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008970#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008971/*[clinic input]
8972os.WCOREDUMP -> bool
8973
8974 status: int
8975 /
8976
8977Return True if the process returning status was dumped to a core file.
8978[clinic start generated code]*/
8979
Larry Hastings2f936352014-08-05 14:04:04 +10008980static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008981os_WCOREDUMP_impl(PyObject *module, int status)
8982/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008983{
8984 WAIT_TYPE wait_status;
8985 WAIT_STATUS_INT(wait_status) = status;
8986 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008987}
8988#endif /* WCOREDUMP */
8989
Larry Hastings2f936352014-08-05 14:04:04 +10008990
Fred Drake106c1a02002-04-23 15:58:02 +00008991#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008992/*[clinic input]
8993os.WIFCONTINUED -> bool
8994
8995 status: int
8996
8997Return True if a particular process was continued from a job control stop.
8998
8999Return True if the process returning status was continued from a
9000job control stop.
9001[clinic start generated code]*/
9002
Larry Hastings2f936352014-08-05 14:04:04 +10009003static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009004os_WIFCONTINUED_impl(PyObject *module, int status)
9005/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009006{
9007 WAIT_TYPE wait_status;
9008 WAIT_STATUS_INT(wait_status) = status;
9009 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009010}
9011#endif /* WIFCONTINUED */
9012
Larry Hastings2f936352014-08-05 14:04:04 +10009013
Guido van Rossumc9641791998-08-04 15:26:23 +00009014#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009015/*[clinic input]
9016os.WIFSTOPPED -> bool
9017
9018 status: int
9019
9020Return True if the process returning status was stopped.
9021[clinic start generated code]*/
9022
Larry Hastings2f936352014-08-05 14:04:04 +10009023static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009024os_WIFSTOPPED_impl(PyObject *module, int status)
9025/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009026{
9027 WAIT_TYPE wait_status;
9028 WAIT_STATUS_INT(wait_status) = status;
9029 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009030}
9031#endif /* WIFSTOPPED */
9032
Larry Hastings2f936352014-08-05 14:04:04 +10009033
Guido van Rossumc9641791998-08-04 15:26:23 +00009034#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009035/*[clinic input]
9036os.WIFSIGNALED -> bool
9037
9038 status: int
9039
9040Return True if the process returning status was terminated by a signal.
9041[clinic start generated code]*/
9042
Larry Hastings2f936352014-08-05 14:04:04 +10009043static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009044os_WIFSIGNALED_impl(PyObject *module, int status)
9045/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009046{
9047 WAIT_TYPE wait_status;
9048 WAIT_STATUS_INT(wait_status) = status;
9049 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009050}
9051#endif /* WIFSIGNALED */
9052
Larry Hastings2f936352014-08-05 14:04:04 +10009053
Guido van Rossumc9641791998-08-04 15:26:23 +00009054#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009055/*[clinic input]
9056os.WIFEXITED -> bool
9057
9058 status: int
9059
9060Return True if the process returning status exited via the exit() system call.
9061[clinic start generated code]*/
9062
Larry Hastings2f936352014-08-05 14:04:04 +10009063static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009064os_WIFEXITED_impl(PyObject *module, int status)
9065/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009066{
9067 WAIT_TYPE wait_status;
9068 WAIT_STATUS_INT(wait_status) = status;
9069 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009070}
9071#endif /* WIFEXITED */
9072
Larry Hastings2f936352014-08-05 14:04:04 +10009073
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009074#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009075/*[clinic input]
9076os.WEXITSTATUS -> int
9077
9078 status: int
9079
9080Return the process return code from status.
9081[clinic start generated code]*/
9082
Larry Hastings2f936352014-08-05 14:04:04 +10009083static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009084os_WEXITSTATUS_impl(PyObject *module, int status)
9085/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009086{
9087 WAIT_TYPE wait_status;
9088 WAIT_STATUS_INT(wait_status) = status;
9089 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009090}
9091#endif /* WEXITSTATUS */
9092
Larry Hastings2f936352014-08-05 14:04:04 +10009093
Guido van Rossumc9641791998-08-04 15:26:23 +00009094#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009095/*[clinic input]
9096os.WTERMSIG -> int
9097
9098 status: int
9099
9100Return the signal that terminated the process that provided the status value.
9101[clinic start generated code]*/
9102
Larry Hastings2f936352014-08-05 14:04:04 +10009103static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009104os_WTERMSIG_impl(PyObject *module, int status)
9105/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009106{
9107 WAIT_TYPE wait_status;
9108 WAIT_STATUS_INT(wait_status) = status;
9109 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009110}
9111#endif /* WTERMSIG */
9112
Larry Hastings2f936352014-08-05 14:04:04 +10009113
Guido van Rossumc9641791998-08-04 15:26:23 +00009114#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009115/*[clinic input]
9116os.WSTOPSIG -> int
9117
9118 status: int
9119
9120Return the signal that stopped the process that provided the status value.
9121[clinic start generated code]*/
9122
Larry Hastings2f936352014-08-05 14:04:04 +10009123static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009124os_WSTOPSIG_impl(PyObject *module, int status)
9125/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009126{
9127 WAIT_TYPE wait_status;
9128 WAIT_STATUS_INT(wait_status) = status;
9129 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009130}
9131#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009132#endif /* HAVE_SYS_WAIT_H */
9133
9134
Thomas Wouters477c8d52006-05-27 19:21:47 +00009135#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009136#ifdef _SCO_DS
9137/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9138 needed definitions in sys/statvfs.h */
9139#define _SVID3
9140#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009141#include <sys/statvfs.h>
9142
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009143static PyObject*
9144_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9146 if (v == NULL)
9147 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009148
9149#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009150 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9151 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9152 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9153 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9154 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9155 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9156 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9157 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9158 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9159 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009160#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9162 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9163 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009164 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009166 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009168 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009169 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009170 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009172 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009173 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009174 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009175 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9176 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009177#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009178 if (PyErr_Occurred()) {
9179 Py_DECREF(v);
9180 return NULL;
9181 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009182
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009184}
9185
Larry Hastings2f936352014-08-05 14:04:04 +10009186
9187/*[clinic input]
9188os.fstatvfs
9189 fd: int
9190 /
9191
9192Perform an fstatvfs system call on the given fd.
9193
9194Equivalent to statvfs(fd).
9195[clinic start generated code]*/
9196
Larry Hastings2f936352014-08-05 14:04:04 +10009197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009198os_fstatvfs_impl(PyObject *module, int fd)
9199/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009200{
9201 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009202 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009203 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009204
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009205 do {
9206 Py_BEGIN_ALLOW_THREADS
9207 result = fstatvfs(fd, &st);
9208 Py_END_ALLOW_THREADS
9209 } while (result != 0 && errno == EINTR &&
9210 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009211 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009212 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009213
Victor Stinner8c62be82010-05-06 00:08:46 +00009214 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009215}
Larry Hastings2f936352014-08-05 14:04:04 +10009216#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009217
9218
Thomas Wouters477c8d52006-05-27 19:21:47 +00009219#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009220#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009221/*[clinic input]
9222os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009223
Larry Hastings2f936352014-08-05 14:04:04 +10009224 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9225
9226Perform a statvfs system call on the given path.
9227
9228path may always be specified as a string.
9229On some platforms, path may also be specified as an open file descriptor.
9230 If this functionality is unavailable, using it raises an exception.
9231[clinic start generated code]*/
9232
Larry Hastings2f936352014-08-05 14:04:04 +10009233static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009234os_statvfs_impl(PyObject *module, path_t *path)
9235/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009236{
9237 int result;
9238 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009239
9240 Py_BEGIN_ALLOW_THREADS
9241#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009242 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009243#ifdef __APPLE__
9244 /* handle weak-linking on Mac OS X 10.3 */
9245 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009246 fd_specified("statvfs", path->fd);
9247 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009248 }
9249#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009250 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009251 }
9252 else
9253#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009254 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009255 Py_END_ALLOW_THREADS
9256
9257 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009258 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009259 }
9260
Larry Hastings2f936352014-08-05 14:04:04 +10009261 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009262}
Larry Hastings2f936352014-08-05 14:04:04 +10009263#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9264
Guido van Rossum94f6f721999-01-06 18:42:14 +00009265
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009266#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009267/*[clinic input]
9268os._getdiskusage
9269
9270 path: Py_UNICODE
9271
9272Return disk usage statistics about the given path as a (total, free) tuple.
9273[clinic start generated code]*/
9274
Larry Hastings2f936352014-08-05 14:04:04 +10009275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009276os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9277/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009278{
9279 BOOL retval;
9280 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009281
9282 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009283 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009284 Py_END_ALLOW_THREADS
9285 if (retval == 0)
9286 return PyErr_SetFromWindowsErr(0);
9287
9288 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9289}
Larry Hastings2f936352014-08-05 14:04:04 +10009290#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009291
9292
Fred Drakec9680921999-12-13 16:37:25 +00009293/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9294 * It maps strings representing configuration variable names to
9295 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009296 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009297 * rarely-used constants. There are three separate tables that use
9298 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009299 *
9300 * This code is always included, even if none of the interfaces that
9301 * need it are included. The #if hackery needed to avoid it would be
9302 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009303 */
9304struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009305 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009306 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009307};
9308
Fred Drake12c6e2d1999-12-14 21:25:03 +00009309static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009310conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009311 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009312{
Christian Heimes217cfd12007-12-02 14:31:20 +00009313 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009314 int value = _PyLong_AsInt(arg);
9315 if (value == -1 && PyErr_Occurred())
9316 return 0;
9317 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009318 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009319 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009320 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009321 /* look up the value in the table using a binary search */
9322 size_t lo = 0;
9323 size_t mid;
9324 size_t hi = tablesize;
9325 int cmp;
9326 const char *confname;
9327 if (!PyUnicode_Check(arg)) {
9328 PyErr_SetString(PyExc_TypeError,
9329 "configuration names must be strings or integers");
9330 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009332 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009333 if (confname == NULL)
9334 return 0;
9335 while (lo < hi) {
9336 mid = (lo + hi) / 2;
9337 cmp = strcmp(confname, table[mid].name);
9338 if (cmp < 0)
9339 hi = mid;
9340 else if (cmp > 0)
9341 lo = mid + 1;
9342 else {
9343 *valuep = table[mid].value;
9344 return 1;
9345 }
9346 }
9347 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9348 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009350}
9351
9352
9353#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9354static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009355#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009357#endif
9358#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009360#endif
Fred Drakec9680921999-12-13 16:37:25 +00009361#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
9397#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
9400#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009402#endif
9403#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009405#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009406#ifdef _PC_ACL_ENABLED
9407 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9408#endif
9409#ifdef _PC_MIN_HOLE_SIZE
9410 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9411#endif
9412#ifdef _PC_ALLOC_SIZE_MIN
9413 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9414#endif
9415#ifdef _PC_REC_INCR_XFER_SIZE
9416 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9417#endif
9418#ifdef _PC_REC_MAX_XFER_SIZE
9419 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9420#endif
9421#ifdef _PC_REC_MIN_XFER_SIZE
9422 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9423#endif
9424#ifdef _PC_REC_XFER_ALIGN
9425 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9426#endif
9427#ifdef _PC_SYMLINK_MAX
9428 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9429#endif
9430#ifdef _PC_XATTR_ENABLED
9431 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9432#endif
9433#ifdef _PC_XATTR_EXISTS
9434 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9435#endif
9436#ifdef _PC_TIMESTAMP_RESOLUTION
9437 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9438#endif
Fred Drakec9680921999-12-13 16:37:25 +00009439};
9440
Fred Drakec9680921999-12-13 16:37:25 +00009441static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009442conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009443{
9444 return conv_confname(arg, valuep, posix_constants_pathconf,
9445 sizeof(posix_constants_pathconf)
9446 / sizeof(struct constdef));
9447}
9448#endif
9449
Larry Hastings2f936352014-08-05 14:04:04 +10009450
Fred Drakec9680921999-12-13 16:37:25 +00009451#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009452/*[clinic input]
9453os.fpathconf -> long
9454
9455 fd: int
9456 name: path_confname
9457 /
9458
9459Return the configuration limit name for the file descriptor fd.
9460
9461If there is no limit, return -1.
9462[clinic start generated code]*/
9463
Larry Hastings2f936352014-08-05 14:04:04 +10009464static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009465os_fpathconf_impl(PyObject *module, int fd, int name)
9466/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009467{
9468 long limit;
9469
9470 errno = 0;
9471 limit = fpathconf(fd, name);
9472 if (limit == -1 && errno != 0)
9473 posix_error();
9474
9475 return limit;
9476}
9477#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009478
9479
9480#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009481/*[clinic input]
9482os.pathconf -> long
9483 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9484 name: path_confname
9485
9486Return the configuration limit name for the file or directory path.
9487
9488If there is no limit, return -1.
9489On some platforms, path may also be specified as an open file descriptor.
9490 If this functionality is unavailable, using it raises an exception.
9491[clinic start generated code]*/
9492
Larry Hastings2f936352014-08-05 14:04:04 +10009493static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009494os_pathconf_impl(PyObject *module, path_t *path, int name)
9495/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009496{
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009498
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009500#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009501 if (path->fd != -1)
9502 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009503 else
9504#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009505 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 if (limit == -1 && errno != 0) {
9507 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009508 /* could be a path or name problem */
9509 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009510 else
Larry Hastings2f936352014-08-05 14:04:04 +10009511 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 }
Larry Hastings2f936352014-08-05 14:04:04 +10009513
9514 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009515}
Larry Hastings2f936352014-08-05 14:04:04 +10009516#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009517
9518#ifdef HAVE_CONFSTR
9519static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009520#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009522#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009523#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009525#endif
9526#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009528#endif
Fred Draked86ed291999-12-15 15:34:33 +00009529#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009531#endif
9532#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009534#endif
9535#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009537#endif
9538#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009540#endif
Fred Drakec9680921999-12-13 16:37:25 +00009541#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
Fred Draked86ed291999-12-15 15:34:33 +00009565#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009567#endif
Fred Drakec9680921999-12-13 16:37:25 +00009568#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
Fred Draked86ed291999-12-15 15:34:33 +00009571#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009573#endif
9574#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009576#endif
9577#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009579#endif
9580#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009582#endif
Fred Drakec9680921999-12-13 16:37:25 +00009583#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
9589#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
9601#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
9604#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
9610#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009612#endif
9613#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009615#endif
9616#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
9619#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009621#endif
9622#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009624#endif
9625#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009627#endif
9628#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
Fred Draked86ed291999-12-15 15:34:33 +00009631#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009633#endif
9634#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009636#endif
9637#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009639#endif
9640#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009642#endif
9643#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009645#endif
9646#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009648#endif
9649#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009651#endif
9652#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009654#endif
9655#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009657#endif
9658#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009660#endif
9661#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009663#endif
9664#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009666#endif
9667#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009669#endif
Fred Drakec9680921999-12-13 16:37:25 +00009670};
9671
9672static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009673conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009674{
9675 return conv_confname(arg, valuep, posix_constants_confstr,
9676 sizeof(posix_constants_confstr)
9677 / sizeof(struct constdef));
9678}
9679
Larry Hastings2f936352014-08-05 14:04:04 +10009680
9681/*[clinic input]
9682os.confstr
9683
9684 name: confstr_confname
9685 /
9686
9687Return a string-valued system configuration variable.
9688[clinic start generated code]*/
9689
Larry Hastings2f936352014-08-05 14:04:04 +10009690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009691os_confstr_impl(PyObject *module, int name)
9692/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009693{
9694 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009695 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009696 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009697
Victor Stinnercb043522010-09-10 23:49:04 +00009698 errno = 0;
9699 len = confstr(name, buffer, sizeof(buffer));
9700 if (len == 0) {
9701 if (errno) {
9702 posix_error();
9703 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009704 }
9705 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009706 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009707 }
9708 }
Victor Stinnercb043522010-09-10 23:49:04 +00009709
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009710 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009711 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009712 char *buf = PyMem_Malloc(len);
9713 if (buf == NULL)
9714 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009715 len2 = confstr(name, buf, len);
9716 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009717 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009718 PyMem_Free(buf);
9719 }
9720 else
9721 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009722 return result;
9723}
Larry Hastings2f936352014-08-05 14:04:04 +10009724#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009725
9726
9727#ifdef HAVE_SYSCONF
9728static struct constdef posix_constants_sysconf[] = {
9729#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
Fred Draked86ed291999-12-15 15:34:33 +00009759#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009761#endif
9762#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009764#endif
Fred Drakec9680921999-12-13 16:37:25 +00009765#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
Fred Drakec9680921999-12-13 16:37:25 +00009768#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
Fred Draked86ed291999-12-15 15:34:33 +00009783#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009785#endif
Fred Drakec9680921999-12-13 16:37:25 +00009786#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
Fred Draked86ed291999-12-15 15:34:33 +00009801#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009803#endif
Fred Drakec9680921999-12-13 16:37:25 +00009804#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
Fred Draked86ed291999-12-15 15:34:33 +00009873#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009875#endif
Fred Drakec9680921999-12-13 16:37:25 +00009876#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
Fred Draked86ed291999-12-15 15:34:33 +00009885#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009887#endif
Fred Drakec9680921999-12-13 16:37:25 +00009888#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
Fred Draked86ed291999-12-15 15:34:33 +00009891#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009893#endif
9894#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009896#endif
Fred Drakec9680921999-12-13 16:37:25 +00009897#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
Fred Draked86ed291999-12-15 15:34:33 +00009909#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009911#endif
Fred Drakec9680921999-12-13 16:37:25 +00009912#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
Fred Draked86ed291999-12-15 15:34:33 +00009933#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009935#endif
Fred Drakec9680921999-12-13 16:37:25 +00009936#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
Fred Draked86ed291999-12-15 15:34:33 +00009942#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009944#endif
Fred Drakec9680921999-12-13 16:37:25 +00009945#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
Fred Draked86ed291999-12-15 15:34:33 +00009972#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009974#endif
9975#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009977#endif
Fred Drakec9680921999-12-13 16:37:25 +00009978#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
Fred Draked86ed291999-12-15 15:34:33 +000010083#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010085#endif
Fred Drakec9680921999-12-13 16:37:25 +000010086#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221};
10222
10223static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010224conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010225{
10226 return conv_confname(arg, valuep, posix_constants_sysconf,
10227 sizeof(posix_constants_sysconf)
10228 / sizeof(struct constdef));
10229}
10230
Larry Hastings2f936352014-08-05 14:04:04 +100010231
10232/*[clinic input]
10233os.sysconf -> long
10234 name: sysconf_confname
10235 /
10236
10237Return an integer-valued system configuration variable.
10238[clinic start generated code]*/
10239
Larry Hastings2f936352014-08-05 14:04:04 +100010240static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010241os_sysconf_impl(PyObject *module, int name)
10242/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010243{
10244 long value;
10245
10246 errno = 0;
10247 value = sysconf(name);
10248 if (value == -1 && errno != 0)
10249 posix_error();
10250 return value;
10251}
10252#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010253
10254
Fred Drakebec628d1999-12-15 18:31:10 +000010255/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010256 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010257 * the exported dictionaries that are used to publish information about the
10258 * names available on the host platform.
10259 *
10260 * Sorting the table at runtime ensures that the table is properly ordered
10261 * when used, even for platforms we're not able to test on. It also makes
10262 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010263 */
Fred Drakebec628d1999-12-15 18:31:10 +000010264
10265static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010266cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010267{
10268 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010270 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010272
10273 return strcmp(c1->name, c2->name);
10274}
10275
10276static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010277setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010278 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010279{
Fred Drakebec628d1999-12-15 18:31:10 +000010280 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010281 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010282
10283 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10284 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010285 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010287
Barry Warsaw3155db32000-04-13 15:20:40 +000010288 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 PyObject *o = PyLong_FromLong(table[i].value);
10290 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10291 Py_XDECREF(o);
10292 Py_DECREF(d);
10293 return -1;
10294 }
10295 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010296 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010297 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010298}
10299
Fred Drakebec628d1999-12-15 18:31:10 +000010300/* Return -1 on failure, 0 on success. */
10301static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010302setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010303{
10304#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010305 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010306 sizeof(posix_constants_pathconf)
10307 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010308 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010309 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010310#endif
10311#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010312 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010313 sizeof(posix_constants_confstr)
10314 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010315 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010316 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010317#endif
10318#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010319 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010320 sizeof(posix_constants_sysconf)
10321 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010322 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010323 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010324#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010325 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010326}
Fred Draked86ed291999-12-15 15:34:33 +000010327
10328
Larry Hastings2f936352014-08-05 14:04:04 +100010329/*[clinic input]
10330os.abort
10331
10332Abort the interpreter immediately.
10333
10334This function 'dumps core' or otherwise fails in the hardest way possible
10335on the hosting operating system. This function never returns.
10336[clinic start generated code]*/
10337
Larry Hastings2f936352014-08-05 14:04:04 +100010338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010339os_abort_impl(PyObject *module)
10340/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010341{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010342 abort();
10343 /*NOTREACHED*/
10344 Py_FatalError("abort() called from Python code didn't abort!");
10345 return NULL;
10346}
Fred Drakebec628d1999-12-15 18:31:10 +000010347
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010348#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010349/* Grab ShellExecute dynamically from shell32 */
10350static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010351static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10352 LPCWSTR, INT);
10353static int
10354check_ShellExecute()
10355{
10356 HINSTANCE hShell32;
10357
10358 /* only recheck */
10359 if (-1 == has_ShellExecute) {
10360 Py_BEGIN_ALLOW_THREADS
10361 hShell32 = LoadLibraryW(L"SHELL32");
10362 Py_END_ALLOW_THREADS
10363 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010364 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10365 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010366 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010367 } else {
10368 has_ShellExecute = 0;
10369 }
10370 }
10371 return has_ShellExecute;
10372}
10373
10374
Steve Dowercc16be82016-09-08 10:35:16 -070010375/*[clinic input]
10376os.startfile
10377 filepath: path_t
10378 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010379
Steve Dowercc16be82016-09-08 10:35:16 -070010380startfile(filepath [, operation])
10381
10382Start a file with its associated application.
10383
10384When "operation" is not specified or "open", this acts like
10385double-clicking the file in Explorer, or giving the file name as an
10386argument to the DOS "start" command: the file is opened with whatever
10387application (if any) its extension is associated.
10388When another "operation" is given, it specifies what should be done with
10389the file. A typical operation is "print".
10390
10391startfile returns as soon as the associated application is launched.
10392There is no option to wait for the application to close, and no way
10393to retrieve the application's exit status.
10394
10395The filepath is relative to the current directory. If you want to use
10396an absolute path, make sure the first character is not a slash ("/");
10397the underlying Win32 ShellExecute function doesn't work if it is.
10398[clinic start generated code]*/
10399
10400static PyObject *
10401os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10402/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10403{
10404 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010405
10406 if(!check_ShellExecute()) {
10407 /* If the OS doesn't have ShellExecute, return a
10408 NotImplementedError. */
10409 return PyErr_Format(PyExc_NotImplementedError,
10410 "startfile not available on this platform");
10411 }
10412
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010414 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010415 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 Py_END_ALLOW_THREADS
10417
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010419 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010420 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 }
Steve Dowercc16be82016-09-08 10:35:16 -070010422 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010423}
Larry Hastings2f936352014-08-05 14:04:04 +100010424#endif /* MS_WINDOWS */
10425
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010426
Martin v. Löwis438b5342002-12-27 10:16:42 +000010427#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010428/*[clinic input]
10429os.getloadavg
10430
10431Return average recent system load information.
10432
10433Return the number of processes in the system run queue averaged over
10434the last 1, 5, and 15 minutes as a tuple of three floats.
10435Raises OSError if the load average was unobtainable.
10436[clinic start generated code]*/
10437
Larry Hastings2f936352014-08-05 14:04:04 +100010438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010439os_getloadavg_impl(PyObject *module)
10440/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010441{
10442 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010443 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010444 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10445 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010446 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010447 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010448}
Larry Hastings2f936352014-08-05 14:04:04 +100010449#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010450
Larry Hastings2f936352014-08-05 14:04:04 +100010451
10452/*[clinic input]
10453os.device_encoding
10454 fd: int
10455
10456Return a string describing the encoding of a terminal's file descriptor.
10457
10458The file descriptor must be attached to a terminal.
10459If the device is not a terminal, return None.
10460[clinic start generated code]*/
10461
Larry Hastings2f936352014-08-05 14:04:04 +100010462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010463os_device_encoding_impl(PyObject *module, int fd)
10464/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010465{
Brett Cannonefb00c02012-02-29 18:31:31 -050010466 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010467}
10468
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010469
Larry Hastings2f936352014-08-05 14:04:04 +100010470#ifdef HAVE_SETRESUID
10471/*[clinic input]
10472os.setresuid
10473
10474 ruid: uid_t
10475 euid: uid_t
10476 suid: uid_t
10477 /
10478
10479Set the current process's real, effective, and saved user ids.
10480[clinic start generated code]*/
10481
Larry Hastings2f936352014-08-05 14:04:04 +100010482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010483os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10484/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010485{
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 if (setresuid(ruid, euid, suid) < 0)
10487 return posix_error();
10488 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010489}
Larry Hastings2f936352014-08-05 14:04:04 +100010490#endif /* HAVE_SETRESUID */
10491
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010492
10493#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010494/*[clinic input]
10495os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010496
Larry Hastings2f936352014-08-05 14:04:04 +100010497 rgid: gid_t
10498 egid: gid_t
10499 sgid: gid_t
10500 /
10501
10502Set the current process's real, effective, and saved group ids.
10503[clinic start generated code]*/
10504
Larry Hastings2f936352014-08-05 14:04:04 +100010505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010506os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10507/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010508{
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 if (setresgid(rgid, egid, sgid) < 0)
10510 return posix_error();
10511 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010512}
Larry Hastings2f936352014-08-05 14:04:04 +100010513#endif /* HAVE_SETRESGID */
10514
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010515
10516#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010517/*[clinic input]
10518os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010519
Larry Hastings2f936352014-08-05 14:04:04 +100010520Return a tuple of the current process's real, effective, and saved user ids.
10521[clinic start generated code]*/
10522
Larry Hastings2f936352014-08-05 14:04:04 +100010523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010524os_getresuid_impl(PyObject *module)
10525/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010526{
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 if (getresuid(&ruid, &euid, &suid) < 0)
10529 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010530 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10531 _PyLong_FromUid(euid),
10532 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010533}
Larry Hastings2f936352014-08-05 14:04:04 +100010534#endif /* HAVE_GETRESUID */
10535
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010536
10537#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010538/*[clinic input]
10539os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010540
Larry Hastings2f936352014-08-05 14:04:04 +100010541Return a tuple of the current process's real, effective, and saved group ids.
10542[clinic start generated code]*/
10543
Larry Hastings2f936352014-08-05 14:04:04 +100010544static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010545os_getresgid_impl(PyObject *module)
10546/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010547{
10548 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 if (getresgid(&rgid, &egid, &sgid) < 0)
10550 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010551 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10552 _PyLong_FromGid(egid),
10553 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010554}
Larry Hastings2f936352014-08-05 14:04:04 +100010555#endif /* HAVE_GETRESGID */
10556
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010557
Benjamin Peterson9428d532011-09-14 11:45:52 -040010558#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010559/*[clinic input]
10560os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561
Larry Hastings2f936352014-08-05 14:04:04 +100010562 path: path_t(allow_fd=True)
10563 attribute: path_t
10564 *
10565 follow_symlinks: bool = True
10566
10567Return the value of extended attribute attribute on path.
10568
10569path may be either a string or an open file descriptor.
10570If follow_symlinks is False, and the last element of the path is a symbolic
10571 link, getxattr will examine the symbolic link itself instead of the file
10572 the link points to.
10573
10574[clinic start generated code]*/
10575
Larry Hastings2f936352014-08-05 14:04:04 +100010576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010577os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010578 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010579/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010580{
10581 Py_ssize_t i;
10582 PyObject *buffer = NULL;
10583
10584 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10585 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010586
Larry Hastings9cf065c2012-06-22 16:30:09 -070010587 for (i = 0; ; i++) {
10588 void *ptr;
10589 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010590 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010591 Py_ssize_t buffer_size = buffer_sizes[i];
10592 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010593 path_error(path);
10594 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 }
10596 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10597 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010598 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010600
Larry Hastings9cf065c2012-06-22 16:30:09 -070010601 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010602 if (path->fd >= 0)
10603 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010604 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010605 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 else
Larry Hastings2f936352014-08-05 14:04:04 +100010607 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010609
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 if (result < 0) {
10611 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 if (errno == ERANGE)
10613 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010614 path_error(path);
10615 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010617
Larry Hastings9cf065c2012-06-22 16:30:09 -070010618 if (result != buffer_size) {
10619 /* Can only shrink. */
10620 _PyBytes_Resize(&buffer, result);
10621 }
10622 break;
10623 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010624
Larry Hastings9cf065c2012-06-22 16:30:09 -070010625 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626}
10627
Larry Hastings2f936352014-08-05 14:04:04 +100010628
10629/*[clinic input]
10630os.setxattr
10631
10632 path: path_t(allow_fd=True)
10633 attribute: path_t
10634 value: Py_buffer
10635 flags: int = 0
10636 *
10637 follow_symlinks: bool = True
10638
10639Set extended attribute attribute on path to value.
10640
10641path may be either a string or an open file descriptor.
10642If follow_symlinks is False, and the last element of the path is a symbolic
10643 link, setxattr will modify the symbolic link itself instead of the file
10644 the link points to.
10645
10646[clinic start generated code]*/
10647
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010649os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010650 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010651/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652{
Larry Hastings2f936352014-08-05 14:04:04 +100010653 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010654
Larry Hastings2f936352014-08-05 14:04:04 +100010655 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010657
Benjamin Peterson799bd802011-08-31 22:15:17 -040010658 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010659 if (path->fd > -1)
10660 result = fsetxattr(path->fd, attribute->narrow,
10661 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010662 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010663 result = setxattr(path->narrow, attribute->narrow,
10664 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010665 else
Larry Hastings2f936352014-08-05 14:04:04 +100010666 result = lsetxattr(path->narrow, attribute->narrow,
10667 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010668 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010669
Larry Hastings9cf065c2012-06-22 16:30:09 -070010670 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010671 path_error(path);
10672 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010673 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010674
Larry Hastings2f936352014-08-05 14:04:04 +100010675 Py_RETURN_NONE;
10676}
10677
10678
10679/*[clinic input]
10680os.removexattr
10681
10682 path: path_t(allow_fd=True)
10683 attribute: path_t
10684 *
10685 follow_symlinks: bool = True
10686
10687Remove extended attribute attribute on path.
10688
10689path may be either a string or an open file descriptor.
10690If follow_symlinks is False, and the last element of the path is a symbolic
10691 link, removexattr will modify the symbolic link itself instead of the file
10692 the link points to.
10693
10694[clinic start generated code]*/
10695
Larry Hastings2f936352014-08-05 14:04:04 +100010696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010697os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010698 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010699/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010700{
10701 ssize_t result;
10702
10703 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10704 return NULL;
10705
10706 Py_BEGIN_ALLOW_THREADS;
10707 if (path->fd > -1)
10708 result = fremovexattr(path->fd, attribute->narrow);
10709 else if (follow_symlinks)
10710 result = removexattr(path->narrow, attribute->narrow);
10711 else
10712 result = lremovexattr(path->narrow, attribute->narrow);
10713 Py_END_ALLOW_THREADS;
10714
10715 if (result) {
10716 return path_error(path);
10717 }
10718
10719 Py_RETURN_NONE;
10720}
10721
10722
10723/*[clinic input]
10724os.listxattr
10725
10726 path: path_t(allow_fd=True, nullable=True) = None
10727 *
10728 follow_symlinks: bool = True
10729
10730Return a list of extended attributes on path.
10731
10732path may be either None, a string, or an open file descriptor.
10733if path is None, listxattr will examine the current directory.
10734If follow_symlinks is False, and the last element of the path is a symbolic
10735 link, listxattr will examine the symbolic link itself instead of the file
10736 the link points to.
10737[clinic start generated code]*/
10738
Larry Hastings2f936352014-08-05 14:04:04 +100010739static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010740os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10741/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010742{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 Py_ssize_t i;
10744 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010745 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010746 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010747
Larry Hastings2f936352014-08-05 14:04:04 +100010748 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010750
Larry Hastings2f936352014-08-05 14:04:04 +100010751 name = path->narrow ? path->narrow : ".";
10752
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010754 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010756 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 Py_ssize_t buffer_size = buffer_sizes[i];
10758 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010759 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010760 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761 break;
10762 }
10763 buffer = PyMem_MALLOC(buffer_size);
10764 if (!buffer) {
10765 PyErr_NoMemory();
10766 break;
10767 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010768
Larry Hastings9cf065c2012-06-22 16:30:09 -070010769 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010770 if (path->fd > -1)
10771 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 else if (follow_symlinks)
10773 length = listxattr(name, buffer, buffer_size);
10774 else
10775 length = llistxattr(name, buffer, buffer_size);
10776 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010777
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010779 if (errno == ERANGE) {
10780 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010781 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010783 }
Larry Hastings2f936352014-08-05 14:04:04 +100010784 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010785 break;
10786 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010787
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 result = PyList_New(0);
10789 if (!result) {
10790 goto exit;
10791 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010792
Larry Hastings9cf065c2012-06-22 16:30:09 -070010793 end = buffer + length;
10794 for (trace = start = buffer; trace != end; trace++) {
10795 if (!*trace) {
10796 int error;
10797 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10798 trace - start);
10799 if (!attribute) {
10800 Py_DECREF(result);
10801 result = NULL;
10802 goto exit;
10803 }
10804 error = PyList_Append(result, attribute);
10805 Py_DECREF(attribute);
10806 if (error) {
10807 Py_DECREF(result);
10808 result = NULL;
10809 goto exit;
10810 }
10811 start = trace + 1;
10812 }
10813 }
10814 break;
10815 }
10816exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 if (buffer)
10818 PyMem_FREE(buffer);
10819 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010821#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010822
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010823
Larry Hastings2f936352014-08-05 14:04:04 +100010824/*[clinic input]
10825os.urandom
10826
10827 size: Py_ssize_t
10828 /
10829
10830Return a bytes object containing random bytes suitable for cryptographic use.
10831[clinic start generated code]*/
10832
Larry Hastings2f936352014-08-05 14:04:04 +100010833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010834os_urandom_impl(PyObject *module, Py_ssize_t size)
10835/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010836{
10837 PyObject *bytes;
10838 int result;
10839
Georg Brandl2fb477c2012-02-21 00:33:36 +010010840 if (size < 0)
10841 return PyErr_Format(PyExc_ValueError,
10842 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010843 bytes = PyBytes_FromStringAndSize(NULL, size);
10844 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010845 return NULL;
10846
Victor Stinnere66987e2016-09-06 16:33:52 -070010847 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010848 if (result == -1) {
10849 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010850 return NULL;
10851 }
Larry Hastings2f936352014-08-05 14:04:04 +100010852 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010853}
10854
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010855/* Terminal size querying */
10856
10857static PyTypeObject TerminalSizeType;
10858
10859PyDoc_STRVAR(TerminalSize_docstring,
10860 "A tuple of (columns, lines) for holding terminal window size");
10861
10862static PyStructSequence_Field TerminalSize_fields[] = {
10863 {"columns", "width of the terminal window in characters"},
10864 {"lines", "height of the terminal window in characters"},
10865 {NULL, NULL}
10866};
10867
10868static PyStructSequence_Desc TerminalSize_desc = {
10869 "os.terminal_size",
10870 TerminalSize_docstring,
10871 TerminalSize_fields,
10872 2,
10873};
10874
10875#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010876/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010877PyDoc_STRVAR(termsize__doc__,
10878 "Return the size of the terminal window as (columns, lines).\n" \
10879 "\n" \
10880 "The optional argument fd (default standard output) specifies\n" \
10881 "which file descriptor should be queried.\n" \
10882 "\n" \
10883 "If the file descriptor is not connected to a terminal, an OSError\n" \
10884 "is thrown.\n" \
10885 "\n" \
10886 "This function will only be defined if an implementation is\n" \
10887 "available for this system.\n" \
10888 "\n" \
10889 "shutil.get_terminal_size is the high-level function which should \n" \
10890 "normally be used, os.get_terminal_size is the low-level implementation.");
10891
10892static PyObject*
10893get_terminal_size(PyObject *self, PyObject *args)
10894{
10895 int columns, lines;
10896 PyObject *termsize;
10897
10898 int fd = fileno(stdout);
10899 /* Under some conditions stdout may not be connected and
10900 * fileno(stdout) may point to an invalid file descriptor. For example
10901 * GUI apps don't have valid standard streams by default.
10902 *
10903 * If this happens, and the optional fd argument is not present,
10904 * the ioctl below will fail returning EBADF. This is what we want.
10905 */
10906
10907 if (!PyArg_ParseTuple(args, "|i", &fd))
10908 return NULL;
10909
10910#ifdef TERMSIZE_USE_IOCTL
10911 {
10912 struct winsize w;
10913 if (ioctl(fd, TIOCGWINSZ, &w))
10914 return PyErr_SetFromErrno(PyExc_OSError);
10915 columns = w.ws_col;
10916 lines = w.ws_row;
10917 }
10918#endif /* TERMSIZE_USE_IOCTL */
10919
10920#ifdef TERMSIZE_USE_CONIO
10921 {
10922 DWORD nhandle;
10923 HANDLE handle;
10924 CONSOLE_SCREEN_BUFFER_INFO csbi;
10925 switch (fd) {
10926 case 0: nhandle = STD_INPUT_HANDLE;
10927 break;
10928 case 1: nhandle = STD_OUTPUT_HANDLE;
10929 break;
10930 case 2: nhandle = STD_ERROR_HANDLE;
10931 break;
10932 default:
10933 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10934 }
10935 handle = GetStdHandle(nhandle);
10936 if (handle == NULL)
10937 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10938 if (handle == INVALID_HANDLE_VALUE)
10939 return PyErr_SetFromWindowsErr(0);
10940
10941 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10942 return PyErr_SetFromWindowsErr(0);
10943
10944 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10945 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10946 }
10947#endif /* TERMSIZE_USE_CONIO */
10948
10949 termsize = PyStructSequence_New(&TerminalSizeType);
10950 if (termsize == NULL)
10951 return NULL;
10952 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10953 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10954 if (PyErr_Occurred()) {
10955 Py_DECREF(termsize);
10956 return NULL;
10957 }
10958 return termsize;
10959}
10960#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10961
Larry Hastings2f936352014-08-05 14:04:04 +100010962
10963/*[clinic input]
10964os.cpu_count
10965
Charles-François Natali80d62e62015-08-13 20:37:08 +010010966Return the number of CPUs in the system; return None if indeterminable.
10967
10968This number is not equivalent to the number of CPUs the current process can
10969use. The number of usable CPUs can be obtained with
10970``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010971[clinic start generated code]*/
10972
Larry Hastings2f936352014-08-05 14:04:04 +100010973static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010974os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010975/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010976{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010977 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010978#ifdef MS_WINDOWS
10979 SYSTEM_INFO sysinfo;
10980 GetSystemInfo(&sysinfo);
10981 ncpu = sysinfo.dwNumberOfProcessors;
10982#elif defined(__hpux)
10983 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10984#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10985 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010986#elif defined(__DragonFly__) || \
10987 defined(__OpenBSD__) || \
10988 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010989 defined(__NetBSD__) || \
10990 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010991 int mib[2];
10992 size_t len = sizeof(ncpu);
10993 mib[0] = CTL_HW;
10994 mib[1] = HW_NCPU;
10995 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10996 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010997#endif
10998 if (ncpu >= 1)
10999 return PyLong_FromLong(ncpu);
11000 else
11001 Py_RETURN_NONE;
11002}
11003
Victor Stinnerdaf45552013-08-28 00:53:59 +020011004
Larry Hastings2f936352014-08-05 14:04:04 +100011005/*[clinic input]
11006os.get_inheritable -> bool
11007
11008 fd: int
11009 /
11010
11011Get the close-on-exe flag of the specified file descriptor.
11012[clinic start generated code]*/
11013
Larry Hastings2f936352014-08-05 14:04:04 +100011014static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011015os_get_inheritable_impl(PyObject *module, int fd)
11016/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011017{
Steve Dower8fc89802015-04-12 00:26:27 -040011018 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011019 _Py_BEGIN_SUPPRESS_IPH
11020 return_value = _Py_get_inheritable(fd);
11021 _Py_END_SUPPRESS_IPH
11022 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011023}
11024
11025
11026/*[clinic input]
11027os.set_inheritable
11028 fd: int
11029 inheritable: int
11030 /
11031
11032Set the inheritable flag of the specified file descriptor.
11033[clinic start generated code]*/
11034
Larry Hastings2f936352014-08-05 14:04:04 +100011035static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011036os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11037/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011038{
Steve Dower8fc89802015-04-12 00:26:27 -040011039 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011040
Steve Dower8fc89802015-04-12 00:26:27 -040011041 _Py_BEGIN_SUPPRESS_IPH
11042 result = _Py_set_inheritable(fd, inheritable, NULL);
11043 _Py_END_SUPPRESS_IPH
11044 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011045 return NULL;
11046 Py_RETURN_NONE;
11047}
11048
11049
11050#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011051/*[clinic input]
11052os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011053 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011054 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011055
Larry Hastings2f936352014-08-05 14:04:04 +100011056Get the close-on-exe flag of the specified file descriptor.
11057[clinic start generated code]*/
11058
Larry Hastings2f936352014-08-05 14:04:04 +100011059static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011060os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011061/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011062{
11063 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011064
11065 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11066 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011067 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011068 }
11069
Larry Hastings2f936352014-08-05 14:04:04 +100011070 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011071}
11072
Victor Stinnerdaf45552013-08-28 00:53:59 +020011073
Larry Hastings2f936352014-08-05 14:04:04 +100011074/*[clinic input]
11075os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011076 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011077 inheritable: bool
11078 /
11079
11080Set the inheritable flag of the specified handle.
11081[clinic start generated code]*/
11082
Larry Hastings2f936352014-08-05 14:04:04 +100011083static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011084os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011085 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011086/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011087{
11088 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011089 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11090 PyErr_SetFromWindowsErr(0);
11091 return NULL;
11092 }
11093 Py_RETURN_NONE;
11094}
Larry Hastings2f936352014-08-05 14:04:04 +100011095#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011096
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011097#ifndef MS_WINDOWS
11098PyDoc_STRVAR(get_blocking__doc__,
11099 "get_blocking(fd) -> bool\n" \
11100 "\n" \
11101 "Get the blocking mode of the file descriptor:\n" \
11102 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11103
11104static PyObject*
11105posix_get_blocking(PyObject *self, PyObject *args)
11106{
11107 int fd;
11108 int blocking;
11109
11110 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11111 return NULL;
11112
Steve Dower8fc89802015-04-12 00:26:27 -040011113 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011114 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011115 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011116 if (blocking < 0)
11117 return NULL;
11118 return PyBool_FromLong(blocking);
11119}
11120
11121PyDoc_STRVAR(set_blocking__doc__,
11122 "set_blocking(fd, blocking)\n" \
11123 "\n" \
11124 "Set the blocking mode of the specified file descriptor.\n" \
11125 "Set the O_NONBLOCK flag if blocking is False,\n" \
11126 "clear the O_NONBLOCK flag otherwise.");
11127
11128static PyObject*
11129posix_set_blocking(PyObject *self, PyObject *args)
11130{
Steve Dower8fc89802015-04-12 00:26:27 -040011131 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011132
11133 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11134 return NULL;
11135
Steve Dower8fc89802015-04-12 00:26:27 -040011136 _Py_BEGIN_SUPPRESS_IPH
11137 result = _Py_set_blocking(fd, blocking);
11138 _Py_END_SUPPRESS_IPH
11139 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011140 return NULL;
11141 Py_RETURN_NONE;
11142}
11143#endif /* !MS_WINDOWS */
11144
11145
Victor Stinner6036e442015-03-08 01:58:04 +010011146PyDoc_STRVAR(posix_scandir__doc__,
11147"scandir(path='.') -> iterator of DirEntry objects for given path");
11148
11149static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11150
11151typedef struct {
11152 PyObject_HEAD
11153 PyObject *name;
11154 PyObject *path;
11155 PyObject *stat;
11156 PyObject *lstat;
11157#ifdef MS_WINDOWS
11158 struct _Py_stat_struct win32_lstat;
11159 __int64 win32_file_index;
11160 int got_file_index;
11161#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011162#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011163 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011164#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011165 ino_t d_ino;
11166#endif
11167} DirEntry;
11168
11169static void
11170DirEntry_dealloc(DirEntry *entry)
11171{
11172 Py_XDECREF(entry->name);
11173 Py_XDECREF(entry->path);
11174 Py_XDECREF(entry->stat);
11175 Py_XDECREF(entry->lstat);
11176 Py_TYPE(entry)->tp_free((PyObject *)entry);
11177}
11178
11179/* Forward reference */
11180static int
11181DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11182
11183/* Set exception and return -1 on error, 0 for False, 1 for True */
11184static int
11185DirEntry_is_symlink(DirEntry *self)
11186{
11187#ifdef MS_WINDOWS
11188 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011189#elif defined(HAVE_DIRENT_D_TYPE)
11190 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011191 if (self->d_type != DT_UNKNOWN)
11192 return self->d_type == DT_LNK;
11193 else
11194 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011195#else
11196 /* POSIX without d_type */
11197 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011198#endif
11199}
11200
11201static PyObject *
11202DirEntry_py_is_symlink(DirEntry *self)
11203{
11204 int result;
11205
11206 result = DirEntry_is_symlink(self);
11207 if (result == -1)
11208 return NULL;
11209 return PyBool_FromLong(result);
11210}
11211
11212static PyObject *
11213DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11214{
11215 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011216 STRUCT_STAT st;
11217 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011218
11219#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011220 if (PyUnicode_FSDecoder(self->path, &ub)) {
11221 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011222#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011223 if (PyUnicode_FSConverter(self->path, &ub)) {
11224 const char *path = PyBytes_AS_STRING(ub);
11225#endif
11226 if (follow_symlinks)
11227 result = STAT(path, &st);
11228 else
11229 result = LSTAT(path, &st);
11230 Py_DECREF(ub);
11231 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011232 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011233
11234 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011235 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011236
11237 return _pystat_fromstructstat(&st);
11238}
11239
11240static PyObject *
11241DirEntry_get_lstat(DirEntry *self)
11242{
11243 if (!self->lstat) {
11244#ifdef MS_WINDOWS
11245 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11246#else /* POSIX */
11247 self->lstat = DirEntry_fetch_stat(self, 0);
11248#endif
11249 }
11250 Py_XINCREF(self->lstat);
11251 return self->lstat;
11252}
11253
11254static PyObject *
11255DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11256{
11257 if (!follow_symlinks)
11258 return DirEntry_get_lstat(self);
11259
11260 if (!self->stat) {
11261 int result = DirEntry_is_symlink(self);
11262 if (result == -1)
11263 return NULL;
11264 else if (result)
11265 self->stat = DirEntry_fetch_stat(self, 1);
11266 else
11267 self->stat = DirEntry_get_lstat(self);
11268 }
11269
11270 Py_XINCREF(self->stat);
11271 return self->stat;
11272}
11273
11274static PyObject *
11275DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11276{
11277 int follow_symlinks = 1;
11278
11279 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11280 follow_symlinks_keywords, &follow_symlinks))
11281 return NULL;
11282
11283 return DirEntry_get_stat(self, follow_symlinks);
11284}
11285
11286/* Set exception and return -1 on error, 0 for False, 1 for True */
11287static int
11288DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11289{
11290 PyObject *stat = NULL;
11291 PyObject *st_mode = NULL;
11292 long mode;
11293 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011294#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011295 int is_symlink;
11296 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011297#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011298#ifdef MS_WINDOWS
11299 unsigned long dir_bits;
11300#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011301 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011302
11303#ifdef MS_WINDOWS
11304 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11305 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011306#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011307 is_symlink = self->d_type == DT_LNK;
11308 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11309#endif
11310
Victor Stinner35a97c02015-03-08 02:59:09 +010011311#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011312 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011313#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011314 stat = DirEntry_get_stat(self, follow_symlinks);
11315 if (!stat) {
11316 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11317 /* If file doesn't exist (anymore), then return False
11318 (i.e., say it's not a file/directory) */
11319 PyErr_Clear();
11320 return 0;
11321 }
11322 goto error;
11323 }
11324 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11325 if (!st_mode)
11326 goto error;
11327
11328 mode = PyLong_AsLong(st_mode);
11329 if (mode == -1 && PyErr_Occurred())
11330 goto error;
11331 Py_CLEAR(st_mode);
11332 Py_CLEAR(stat);
11333 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011334#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011335 }
11336 else if (is_symlink) {
11337 assert(mode_bits != S_IFLNK);
11338 result = 0;
11339 }
11340 else {
11341 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11342#ifdef MS_WINDOWS
11343 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11344 if (mode_bits == S_IFDIR)
11345 result = dir_bits != 0;
11346 else
11347 result = dir_bits == 0;
11348#else /* POSIX */
11349 if (mode_bits == S_IFDIR)
11350 result = self->d_type == DT_DIR;
11351 else
11352 result = self->d_type == DT_REG;
11353#endif
11354 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011355#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011356
11357 return result;
11358
11359error:
11360 Py_XDECREF(st_mode);
11361 Py_XDECREF(stat);
11362 return -1;
11363}
11364
11365static PyObject *
11366DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11367{
11368 int result;
11369
11370 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11371 if (result == -1)
11372 return NULL;
11373 return PyBool_FromLong(result);
11374}
11375
11376static PyObject *
11377DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11378{
11379 int follow_symlinks = 1;
11380
11381 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11382 follow_symlinks_keywords, &follow_symlinks))
11383 return NULL;
11384
11385 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11386}
11387
11388static PyObject *
11389DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11390{
11391 int follow_symlinks = 1;
11392
11393 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11394 follow_symlinks_keywords, &follow_symlinks))
11395 return NULL;
11396
11397 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11398}
11399
11400static PyObject *
11401DirEntry_inode(DirEntry *self)
11402{
11403#ifdef MS_WINDOWS
11404 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011405 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011406 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011407 STRUCT_STAT stat;
11408 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011409
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011410 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011411 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011412 path = PyUnicode_AsUnicode(unicode);
11413 result = LSTAT(path, &stat);
11414 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011415
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011416 if (result != 0)
11417 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011418
11419 self->win32_file_index = stat.st_ino;
11420 self->got_file_index = 1;
11421 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011422 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011423#else /* POSIX */
11424#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011425 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011426#else
11427 return PyLong_FromLong((long)self->d_ino);
11428#endif
11429#endif
11430}
11431
11432static PyObject *
11433DirEntry_repr(DirEntry *self)
11434{
11435 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11436}
11437
Brett Cannon96881cd2016-06-10 14:37:21 -070011438static PyObject *
11439DirEntry_fspath(DirEntry *self)
11440{
11441 Py_INCREF(self->path);
11442 return self->path;
11443}
11444
Victor Stinner6036e442015-03-08 01:58:04 +010011445static PyMemberDef DirEntry_members[] = {
11446 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11447 "the entry's base filename, relative to scandir() \"path\" argument"},
11448 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11449 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11450 {NULL}
11451};
11452
11453static PyMethodDef DirEntry_methods[] = {
11454 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11455 "return True if the entry is a directory; cached per entry"
11456 },
11457 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11458 "return True if the entry is a file; cached per entry"
11459 },
11460 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11461 "return True if the entry is a symbolic link; cached per entry"
11462 },
11463 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11464 "return stat_result object for the entry; cached per entry"
11465 },
11466 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11467 "return inode of the entry; cached per entry",
11468 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011469 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11470 "returns the path for the entry",
11471 },
Victor Stinner6036e442015-03-08 01:58:04 +010011472 {NULL}
11473};
11474
Benjamin Peterson5646de42015-04-12 17:56:34 -040011475static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011476 PyVarObject_HEAD_INIT(NULL, 0)
11477 MODNAME ".DirEntry", /* tp_name */
11478 sizeof(DirEntry), /* tp_basicsize */
11479 0, /* tp_itemsize */
11480 /* methods */
11481 (destructor)DirEntry_dealloc, /* tp_dealloc */
11482 0, /* tp_print */
11483 0, /* tp_getattr */
11484 0, /* tp_setattr */
11485 0, /* tp_compare */
11486 (reprfunc)DirEntry_repr, /* tp_repr */
11487 0, /* tp_as_number */
11488 0, /* tp_as_sequence */
11489 0, /* tp_as_mapping */
11490 0, /* tp_hash */
11491 0, /* tp_call */
11492 0, /* tp_str */
11493 0, /* tp_getattro */
11494 0, /* tp_setattro */
11495 0, /* tp_as_buffer */
11496 Py_TPFLAGS_DEFAULT, /* tp_flags */
11497 0, /* tp_doc */
11498 0, /* tp_traverse */
11499 0, /* tp_clear */
11500 0, /* tp_richcompare */
11501 0, /* tp_weaklistoffset */
11502 0, /* tp_iter */
11503 0, /* tp_iternext */
11504 DirEntry_methods, /* tp_methods */
11505 DirEntry_members, /* tp_members */
11506};
11507
11508#ifdef MS_WINDOWS
11509
11510static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011511join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011512{
11513 Py_ssize_t path_len;
11514 Py_ssize_t size;
11515 wchar_t *result;
11516 wchar_t ch;
11517
11518 if (!path_wide) { /* Default arg: "." */
11519 path_wide = L".";
11520 path_len = 1;
11521 }
11522 else {
11523 path_len = wcslen(path_wide);
11524 }
11525
11526 /* The +1's are for the path separator and the NUL */
11527 size = path_len + 1 + wcslen(filename) + 1;
11528 result = PyMem_New(wchar_t, size);
11529 if (!result) {
11530 PyErr_NoMemory();
11531 return NULL;
11532 }
11533 wcscpy(result, path_wide);
11534 if (path_len > 0) {
11535 ch = result[path_len - 1];
11536 if (ch != SEP && ch != ALTSEP && ch != L':')
11537 result[path_len++] = SEP;
11538 wcscpy(result + path_len, filename);
11539 }
11540 return result;
11541}
11542
11543static PyObject *
11544DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11545{
11546 DirEntry *entry;
11547 BY_HANDLE_FILE_INFORMATION file_info;
11548 ULONG reparse_tag;
11549 wchar_t *joined_path;
11550
11551 entry = PyObject_New(DirEntry, &DirEntryType);
11552 if (!entry)
11553 return NULL;
11554 entry->name = NULL;
11555 entry->path = NULL;
11556 entry->stat = NULL;
11557 entry->lstat = NULL;
11558 entry->got_file_index = 0;
11559
11560 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11561 if (!entry->name)
11562 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011563 if (path->narrow) {
11564 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11565 if (!entry->name)
11566 goto error;
11567 }
Victor Stinner6036e442015-03-08 01:58:04 +010011568
11569 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11570 if (!joined_path)
11571 goto error;
11572
11573 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11574 PyMem_Free(joined_path);
11575 if (!entry->path)
11576 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011577 if (path->narrow) {
11578 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11579 if (!entry->path)
11580 goto error;
11581 }
Victor Stinner6036e442015-03-08 01:58:04 +010011582
Steve Dowercc16be82016-09-08 10:35:16 -070011583 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011584 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11585
11586 return (PyObject *)entry;
11587
11588error:
11589 Py_DECREF(entry);
11590 return NULL;
11591}
11592
11593#else /* POSIX */
11594
11595static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011596join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011597{
11598 Py_ssize_t path_len;
11599 Py_ssize_t size;
11600 char *result;
11601
11602 if (!path_narrow) { /* Default arg: "." */
11603 path_narrow = ".";
11604 path_len = 1;
11605 }
11606 else {
11607 path_len = strlen(path_narrow);
11608 }
11609
11610 if (filename_len == -1)
11611 filename_len = strlen(filename);
11612
11613 /* The +1's are for the path separator and the NUL */
11614 size = path_len + 1 + filename_len + 1;
11615 result = PyMem_New(char, size);
11616 if (!result) {
11617 PyErr_NoMemory();
11618 return NULL;
11619 }
11620 strcpy(result, path_narrow);
11621 if (path_len > 0 && result[path_len - 1] != '/')
11622 result[path_len++] = '/';
11623 strcpy(result + path_len, filename);
11624 return result;
11625}
11626
11627static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011628DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011629 ino_t d_ino
11630#ifdef HAVE_DIRENT_D_TYPE
11631 , unsigned char d_type
11632#endif
11633 )
Victor Stinner6036e442015-03-08 01:58:04 +010011634{
11635 DirEntry *entry;
11636 char *joined_path;
11637
11638 entry = PyObject_New(DirEntry, &DirEntryType);
11639 if (!entry)
11640 return NULL;
11641 entry->name = NULL;
11642 entry->path = NULL;
11643 entry->stat = NULL;
11644 entry->lstat = NULL;
11645
11646 joined_path = join_path_filename(path->narrow, name, name_len);
11647 if (!joined_path)
11648 goto error;
11649
11650 if (!path->narrow || !PyBytes_Check(path->object)) {
11651 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11652 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11653 }
11654 else {
11655 entry->name = PyBytes_FromStringAndSize(name, name_len);
11656 entry->path = PyBytes_FromString(joined_path);
11657 }
11658 PyMem_Free(joined_path);
11659 if (!entry->name || !entry->path)
11660 goto error;
11661
Victor Stinner35a97c02015-03-08 02:59:09 +010011662#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011663 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011664#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011665 entry->d_ino = d_ino;
11666
11667 return (PyObject *)entry;
11668
11669error:
11670 Py_XDECREF(entry);
11671 return NULL;
11672}
11673
11674#endif
11675
11676
11677typedef struct {
11678 PyObject_HEAD
11679 path_t path;
11680#ifdef MS_WINDOWS
11681 HANDLE handle;
11682 WIN32_FIND_DATAW file_data;
11683 int first_time;
11684#else /* POSIX */
11685 DIR *dirp;
11686#endif
11687} ScandirIterator;
11688
11689#ifdef MS_WINDOWS
11690
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011691static int
11692ScandirIterator_is_closed(ScandirIterator *iterator)
11693{
11694 return iterator->handle == INVALID_HANDLE_VALUE;
11695}
11696
Victor Stinner6036e442015-03-08 01:58:04 +010011697static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011698ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011699{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011700 HANDLE handle = iterator->handle;
11701
11702 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011703 return;
11704
Victor Stinner6036e442015-03-08 01:58:04 +010011705 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011706 Py_BEGIN_ALLOW_THREADS
11707 FindClose(handle);
11708 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011709}
11710
11711static PyObject *
11712ScandirIterator_iternext(ScandirIterator *iterator)
11713{
11714 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11715 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011716 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011717
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011718 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011719 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011720 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011721
11722 while (1) {
11723 if (!iterator->first_time) {
11724 Py_BEGIN_ALLOW_THREADS
11725 success = FindNextFileW(iterator->handle, file_data);
11726 Py_END_ALLOW_THREADS
11727 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011728 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011729 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011730 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011731 break;
11732 }
11733 }
11734 iterator->first_time = 0;
11735
11736 /* Skip over . and .. */
11737 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011738 wcscmp(file_data->cFileName, L"..") != 0) {
11739 entry = DirEntry_from_find_data(&iterator->path, file_data);
11740 if (!entry)
11741 break;
11742 return entry;
11743 }
Victor Stinner6036e442015-03-08 01:58:04 +010011744
11745 /* Loop till we get a non-dot directory or finish iterating */
11746 }
11747
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011748 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011749 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011750 return NULL;
11751}
11752
11753#else /* POSIX */
11754
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011755static int
11756ScandirIterator_is_closed(ScandirIterator *iterator)
11757{
11758 return !iterator->dirp;
11759}
11760
Victor Stinner6036e442015-03-08 01:58:04 +010011761static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011762ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011763{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011764 DIR *dirp = iterator->dirp;
11765
11766 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011767 return;
11768
Victor Stinner6036e442015-03-08 01:58:04 +010011769 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011770 Py_BEGIN_ALLOW_THREADS
11771 closedir(dirp);
11772 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011773 return;
11774}
11775
11776static PyObject *
11777ScandirIterator_iternext(ScandirIterator *iterator)
11778{
11779 struct dirent *direntp;
11780 Py_ssize_t name_len;
11781 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011782 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011783
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011784 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011785 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011786 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011787
11788 while (1) {
11789 errno = 0;
11790 Py_BEGIN_ALLOW_THREADS
11791 direntp = readdir(iterator->dirp);
11792 Py_END_ALLOW_THREADS
11793
11794 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011795 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011796 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011797 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011798 break;
11799 }
11800
11801 /* Skip over . and .. */
11802 name_len = NAMLEN(direntp);
11803 is_dot = direntp->d_name[0] == '.' &&
11804 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11805 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011806 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011807 name_len, direntp->d_ino
11808#ifdef HAVE_DIRENT_D_TYPE
11809 , direntp->d_type
11810#endif
11811 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011812 if (!entry)
11813 break;
11814 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011815 }
11816
11817 /* Loop till we get a non-dot directory or finish iterating */
11818 }
11819
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011820 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011821 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011822 return NULL;
11823}
11824
11825#endif
11826
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011827static PyObject *
11828ScandirIterator_close(ScandirIterator *self, PyObject *args)
11829{
11830 ScandirIterator_closedir(self);
11831 Py_RETURN_NONE;
11832}
11833
11834static PyObject *
11835ScandirIterator_enter(PyObject *self, PyObject *args)
11836{
11837 Py_INCREF(self);
11838 return self;
11839}
11840
11841static PyObject *
11842ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11843{
11844 ScandirIterator_closedir(self);
11845 Py_RETURN_NONE;
11846}
11847
Victor Stinner6036e442015-03-08 01:58:04 +010011848static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011849ScandirIterator_finalize(ScandirIterator *iterator)
11850{
11851 PyObject *error_type, *error_value, *error_traceback;
11852
11853 /* Save the current exception, if any. */
11854 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11855
11856 if (!ScandirIterator_is_closed(iterator)) {
11857 ScandirIterator_closedir(iterator);
11858
11859 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11860 "unclosed scandir iterator %R", iterator)) {
11861 /* Spurious errors can appear at shutdown */
11862 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11863 PyErr_WriteUnraisable((PyObject *) iterator);
11864 }
11865 }
11866 }
11867
Victor Stinner7bfa4092016-03-23 00:43:54 +010011868 path_cleanup(&iterator->path);
11869
11870 /* Restore the saved exception. */
11871 PyErr_Restore(error_type, error_value, error_traceback);
11872}
11873
11874static void
Victor Stinner6036e442015-03-08 01:58:04 +010011875ScandirIterator_dealloc(ScandirIterator *iterator)
11876{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011877 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11878 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011879
Victor Stinner6036e442015-03-08 01:58:04 +010011880 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11881}
11882
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011883static PyMethodDef ScandirIterator_methods[] = {
11884 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11885 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11886 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11887 {NULL}
11888};
11889
Benjamin Peterson5646de42015-04-12 17:56:34 -040011890static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011891 PyVarObject_HEAD_INIT(NULL, 0)
11892 MODNAME ".ScandirIterator", /* tp_name */
11893 sizeof(ScandirIterator), /* tp_basicsize */
11894 0, /* tp_itemsize */
11895 /* methods */
11896 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11897 0, /* tp_print */
11898 0, /* tp_getattr */
11899 0, /* tp_setattr */
11900 0, /* tp_compare */
11901 0, /* tp_repr */
11902 0, /* tp_as_number */
11903 0, /* tp_as_sequence */
11904 0, /* tp_as_mapping */
11905 0, /* tp_hash */
11906 0, /* tp_call */
11907 0, /* tp_str */
11908 0, /* tp_getattro */
11909 0, /* tp_setattro */
11910 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011911 Py_TPFLAGS_DEFAULT
11912 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011913 0, /* tp_doc */
11914 0, /* tp_traverse */
11915 0, /* tp_clear */
11916 0, /* tp_richcompare */
11917 0, /* tp_weaklistoffset */
11918 PyObject_SelfIter, /* tp_iter */
11919 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011920 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011921 0, /* tp_members */
11922 0, /* tp_getset */
11923 0, /* tp_base */
11924 0, /* tp_dict */
11925 0, /* tp_descr_get */
11926 0, /* tp_descr_set */
11927 0, /* tp_dictoffset */
11928 0, /* tp_init */
11929 0, /* tp_alloc */
11930 0, /* tp_new */
11931 0, /* tp_free */
11932 0, /* tp_is_gc */
11933 0, /* tp_bases */
11934 0, /* tp_mro */
11935 0, /* tp_cache */
11936 0, /* tp_subclasses */
11937 0, /* tp_weaklist */
11938 0, /* tp_del */
11939 0, /* tp_version_tag */
11940 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011941};
11942
11943static PyObject *
11944posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11945{
11946 ScandirIterator *iterator;
11947 static char *keywords[] = {"path", NULL};
11948#ifdef MS_WINDOWS
11949 wchar_t *path_strW;
11950#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011951 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011952#endif
11953
11954 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11955 if (!iterator)
11956 return NULL;
11957 memset(&iterator->path, 0, sizeof(path_t));
11958 iterator->path.function_name = "scandir";
11959 iterator->path.nullable = 1;
11960
11961#ifdef MS_WINDOWS
11962 iterator->handle = INVALID_HANDLE_VALUE;
11963#else
11964 iterator->dirp = NULL;
11965#endif
11966
11967 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11968 path_converter, &iterator->path))
11969 goto error;
11970
Victor Stinner6036e442015-03-08 01:58:04 +010011971#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011972 iterator->first_time = 1;
11973
11974 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11975 if (!path_strW)
11976 goto error;
11977
11978 Py_BEGIN_ALLOW_THREADS
11979 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11980 Py_END_ALLOW_THREADS
11981
11982 PyMem_Free(path_strW);
11983
11984 if (iterator->handle == INVALID_HANDLE_VALUE) {
11985 path_error(&iterator->path);
11986 goto error;
11987 }
11988#else /* POSIX */
11989 if (iterator->path.narrow)
11990 path = iterator->path.narrow;
11991 else
11992 path = ".";
11993
11994 errno = 0;
11995 Py_BEGIN_ALLOW_THREADS
11996 iterator->dirp = opendir(path);
11997 Py_END_ALLOW_THREADS
11998
11999 if (!iterator->dirp) {
12000 path_error(&iterator->path);
12001 goto error;
12002 }
12003#endif
12004
12005 return (PyObject *)iterator;
12006
12007error:
12008 Py_DECREF(iterator);
12009 return NULL;
12010}
12011
Ethan Furman410ef8e2016-06-04 12:06:26 -070012012/*
12013 Return the file system path representation of the object.
12014
12015 If the object is str or bytes, then allow it to pass through with
12016 an incremented refcount. If the object defines __fspath__(), then
12017 return the result of that method. All other types raise a TypeError.
12018*/
12019PyObject *
12020PyOS_FSPath(PyObject *path)
12021{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012022 /* For error message reasons, this function is manually inlined in
12023 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012024 _Py_IDENTIFIER(__fspath__);
12025 PyObject *func = NULL;
12026 PyObject *path_repr = NULL;
12027
12028 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12029 Py_INCREF(path);
12030 return path;
12031 }
12032
12033 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12034 if (NULL == func) {
12035 return PyErr_Format(PyExc_TypeError,
12036 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012037 "not %.200s",
12038 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012039 }
12040
12041 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12042 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012043 if (NULL == path_repr) {
12044 return NULL;
12045 }
12046
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012047 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12048 PyErr_Format(PyExc_TypeError,
12049 "expected %.200s.__fspath__() to return str or bytes, "
12050 "not %.200s", Py_TYPE(path)->tp_name,
12051 Py_TYPE(path_repr)->tp_name);
12052 Py_DECREF(path_repr);
12053 return NULL;
12054 }
12055
Ethan Furman410ef8e2016-06-04 12:06:26 -070012056 return path_repr;
12057}
12058
12059/*[clinic input]
12060os.fspath
12061
12062 path: object
12063
12064Return the file system path representation of the object.
12065
Brett Cannonb4f43e92016-06-09 14:32:08 -070012066If the object is str or bytes, then allow it to pass through as-is. If the
12067object defines __fspath__(), then return the result of that method. All other
12068types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012069[clinic start generated code]*/
12070
12071static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012072os_fspath_impl(PyObject *module, PyObject *path)
12073/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012074{
12075 return PyOS_FSPath(path);
12076}
Victor Stinner6036e442015-03-08 01:58:04 +010012077
Victor Stinner9b1f4742016-09-06 16:18:52 -070012078#ifdef HAVE_GETRANDOM_SYSCALL
12079/*[clinic input]
12080os.getrandom
12081
12082 size: Py_ssize_t
12083 flags: int=0
12084
12085Obtain a series of random bytes.
12086[clinic start generated code]*/
12087
12088static PyObject *
12089os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12090/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12091{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012092 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012093 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012094
12095 if (size < 0) {
12096 errno = EINVAL;
12097 return posix_error();
12098 }
12099
Victor Stinnerec2319c2016-09-20 23:00:59 +020012100 bytes = PyBytes_FromStringAndSize(NULL, size);
12101 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012102 PyErr_NoMemory();
12103 return NULL;
12104 }
12105
12106 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012107 n = syscall(SYS_getrandom,
12108 PyBytes_AS_STRING(bytes),
12109 PyBytes_GET_SIZE(bytes),
12110 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012111 if (n < 0 && errno == EINTR) {
12112 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012113 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012114 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012115
12116 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012117 continue;
12118 }
12119 break;
12120 }
12121
12122 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012123 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012124 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012125 }
12126
Victor Stinnerec2319c2016-09-20 23:00:59 +020012127 if (n != size) {
12128 _PyBytes_Resize(&bytes, n);
12129 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012130
12131 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012132
12133error:
12134 Py_DECREF(bytes);
12135 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012136}
12137#endif /* HAVE_GETRANDOM_SYSCALL */
12138
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012139#include "clinic/posixmodule.c.h"
12140
Larry Hastings7726ac92014-01-31 22:03:12 -080012141/*[clinic input]
12142dump buffer
12143[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012144/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012145
Larry Hastings31826802013-10-19 00:09:25 -070012146
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012147static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012148
12149 OS_STAT_METHODDEF
12150 OS_ACCESS_METHODDEF
12151 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012152 OS_CHDIR_METHODDEF
12153 OS_CHFLAGS_METHODDEF
12154 OS_CHMOD_METHODDEF
12155 OS_FCHMOD_METHODDEF
12156 OS_LCHMOD_METHODDEF
12157 OS_CHOWN_METHODDEF
12158 OS_FCHOWN_METHODDEF
12159 OS_LCHOWN_METHODDEF
12160 OS_LCHFLAGS_METHODDEF
12161 OS_CHROOT_METHODDEF
12162 OS_CTERMID_METHODDEF
12163 OS_GETCWD_METHODDEF
12164 OS_GETCWDB_METHODDEF
12165 OS_LINK_METHODDEF
12166 OS_LISTDIR_METHODDEF
12167 OS_LSTAT_METHODDEF
12168 OS_MKDIR_METHODDEF
12169 OS_NICE_METHODDEF
12170 OS_GETPRIORITY_METHODDEF
12171 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012172#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012173 {"readlink", (PyCFunction)posix_readlink,
12174 METH_VARARGS | METH_KEYWORDS,
12175 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012176#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012177#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012178 {"readlink", (PyCFunction)win_readlink,
12179 METH_VARARGS | METH_KEYWORDS,
12180 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012181#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012182 OS_RENAME_METHODDEF
12183 OS_REPLACE_METHODDEF
12184 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012185 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012186 OS_SYMLINK_METHODDEF
12187 OS_SYSTEM_METHODDEF
12188 OS_UMASK_METHODDEF
12189 OS_UNAME_METHODDEF
12190 OS_UNLINK_METHODDEF
12191 OS_REMOVE_METHODDEF
12192 OS_UTIME_METHODDEF
12193 OS_TIMES_METHODDEF
12194 OS__EXIT_METHODDEF
12195 OS_EXECV_METHODDEF
12196 OS_EXECVE_METHODDEF
12197 OS_SPAWNV_METHODDEF
12198 OS_SPAWNVE_METHODDEF
12199 OS_FORK1_METHODDEF
12200 OS_FORK_METHODDEF
12201 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12202 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12203 OS_SCHED_GETPARAM_METHODDEF
12204 OS_SCHED_GETSCHEDULER_METHODDEF
12205 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12206 OS_SCHED_SETPARAM_METHODDEF
12207 OS_SCHED_SETSCHEDULER_METHODDEF
12208 OS_SCHED_YIELD_METHODDEF
12209 OS_SCHED_SETAFFINITY_METHODDEF
12210 OS_SCHED_GETAFFINITY_METHODDEF
12211 OS_OPENPTY_METHODDEF
12212 OS_FORKPTY_METHODDEF
12213 OS_GETEGID_METHODDEF
12214 OS_GETEUID_METHODDEF
12215 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012216#ifdef HAVE_GETGROUPLIST
12217 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12218#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012219 OS_GETGROUPS_METHODDEF
12220 OS_GETPID_METHODDEF
12221 OS_GETPGRP_METHODDEF
12222 OS_GETPPID_METHODDEF
12223 OS_GETUID_METHODDEF
12224 OS_GETLOGIN_METHODDEF
12225 OS_KILL_METHODDEF
12226 OS_KILLPG_METHODDEF
12227 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012228#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012229 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012230#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012231 OS_SETUID_METHODDEF
12232 OS_SETEUID_METHODDEF
12233 OS_SETREUID_METHODDEF
12234 OS_SETGID_METHODDEF
12235 OS_SETEGID_METHODDEF
12236 OS_SETREGID_METHODDEF
12237 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012238#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012239 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012240#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012241 OS_GETPGID_METHODDEF
12242 OS_SETPGRP_METHODDEF
12243 OS_WAIT_METHODDEF
12244 OS_WAIT3_METHODDEF
12245 OS_WAIT4_METHODDEF
12246 OS_WAITID_METHODDEF
12247 OS_WAITPID_METHODDEF
12248 OS_GETSID_METHODDEF
12249 OS_SETSID_METHODDEF
12250 OS_SETPGID_METHODDEF
12251 OS_TCGETPGRP_METHODDEF
12252 OS_TCSETPGRP_METHODDEF
12253 OS_OPEN_METHODDEF
12254 OS_CLOSE_METHODDEF
12255 OS_CLOSERANGE_METHODDEF
12256 OS_DEVICE_ENCODING_METHODDEF
12257 OS_DUP_METHODDEF
12258 OS_DUP2_METHODDEF
12259 OS_LOCKF_METHODDEF
12260 OS_LSEEK_METHODDEF
12261 OS_READ_METHODDEF
12262 OS_READV_METHODDEF
12263 OS_PREAD_METHODDEF
12264 OS_WRITE_METHODDEF
12265 OS_WRITEV_METHODDEF
12266 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012267#ifdef HAVE_SENDFILE
12268 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12269 posix_sendfile__doc__},
12270#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012271 OS_FSTAT_METHODDEF
12272 OS_ISATTY_METHODDEF
12273 OS_PIPE_METHODDEF
12274 OS_PIPE2_METHODDEF
12275 OS_MKFIFO_METHODDEF
12276 OS_MKNOD_METHODDEF
12277 OS_MAJOR_METHODDEF
12278 OS_MINOR_METHODDEF
12279 OS_MAKEDEV_METHODDEF
12280 OS_FTRUNCATE_METHODDEF
12281 OS_TRUNCATE_METHODDEF
12282 OS_POSIX_FALLOCATE_METHODDEF
12283 OS_POSIX_FADVISE_METHODDEF
12284 OS_PUTENV_METHODDEF
12285 OS_UNSETENV_METHODDEF
12286 OS_STRERROR_METHODDEF
12287 OS_FCHDIR_METHODDEF
12288 OS_FSYNC_METHODDEF
12289 OS_SYNC_METHODDEF
12290 OS_FDATASYNC_METHODDEF
12291 OS_WCOREDUMP_METHODDEF
12292 OS_WIFCONTINUED_METHODDEF
12293 OS_WIFSTOPPED_METHODDEF
12294 OS_WIFSIGNALED_METHODDEF
12295 OS_WIFEXITED_METHODDEF
12296 OS_WEXITSTATUS_METHODDEF
12297 OS_WTERMSIG_METHODDEF
12298 OS_WSTOPSIG_METHODDEF
12299 OS_FSTATVFS_METHODDEF
12300 OS_STATVFS_METHODDEF
12301 OS_CONFSTR_METHODDEF
12302 OS_SYSCONF_METHODDEF
12303 OS_FPATHCONF_METHODDEF
12304 OS_PATHCONF_METHODDEF
12305 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012306 OS__GETFULLPATHNAME_METHODDEF
12307 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012308 OS__GETDISKUSAGE_METHODDEF
12309 OS__GETFINALPATHNAME_METHODDEF
12310 OS__GETVOLUMEPATHNAME_METHODDEF
12311 OS_GETLOADAVG_METHODDEF
12312 OS_URANDOM_METHODDEF
12313 OS_SETRESUID_METHODDEF
12314 OS_SETRESGID_METHODDEF
12315 OS_GETRESUID_METHODDEF
12316 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012317
Larry Hastings2f936352014-08-05 14:04:04 +100012318 OS_GETXATTR_METHODDEF
12319 OS_SETXATTR_METHODDEF
12320 OS_REMOVEXATTR_METHODDEF
12321 OS_LISTXATTR_METHODDEF
12322
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012323#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12324 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12325#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012326 OS_CPU_COUNT_METHODDEF
12327 OS_GET_INHERITABLE_METHODDEF
12328 OS_SET_INHERITABLE_METHODDEF
12329 OS_GET_HANDLE_INHERITABLE_METHODDEF
12330 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012331#ifndef MS_WINDOWS
12332 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12333 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12334#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012335 {"scandir", (PyCFunction)posix_scandir,
12336 METH_VARARGS | METH_KEYWORDS,
12337 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012338 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012339 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012340 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012341};
12342
12343
Brian Curtin52173d42010-12-02 18:29:18 +000012344#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012345static int
Brian Curtin52173d42010-12-02 18:29:18 +000012346enable_symlink()
12347{
12348 HANDLE tok;
12349 TOKEN_PRIVILEGES tok_priv;
12350 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012351
12352 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012353 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012354
12355 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012356 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012357
12358 tok_priv.PrivilegeCount = 1;
12359 tok_priv.Privileges[0].Luid = luid;
12360 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12361
12362 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12363 sizeof(TOKEN_PRIVILEGES),
12364 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012365 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012366
Brian Curtin3b4499c2010-12-28 14:31:47 +000012367 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12368 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012369}
12370#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12371
Barry Warsaw4a342091996-12-19 23:50:02 +000012372static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012373all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012374{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012375#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012376 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012377#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012378#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012379 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012380#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012381#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012383#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012384#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012385 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012386#endif
Fred Drakec9680921999-12-13 16:37:25 +000012387#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012388 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012389#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012390#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012391 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012392#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012393#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012394 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012395#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012396#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012397 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012398#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012399#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012401#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012402#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012404#endif
12405#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012407#endif
12408#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012410#endif
12411#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012413#endif
12414#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012416#endif
12417#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012419#endif
12420#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012422#endif
12423#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012424 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012425#endif
12426#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012428#endif
12429#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012430 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#endif
12432#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012433 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012434#endif
12435#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012437#endif
12438#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012439 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012440#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012441#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012442 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012443#endif
12444#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012445 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012446#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012447#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012449#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012450#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012452#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012453#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012454#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012456#endif
12457#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012459#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012460#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012461#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012462 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012463#endif
12464#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012466#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012467#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012468 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012469#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012470#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012472#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012473#ifdef O_TMPFILE
12474 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12475#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012476#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012477 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012478#endif
12479#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012480 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012481#endif
12482#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012484#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012485#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012486 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012487#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012488#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012489 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012490#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012491
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012492
Jesus Cea94363612012-06-22 18:32:07 +020012493#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012494 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012495#endif
12496#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012498#endif
12499
Tim Peters5aa91602002-01-30 05:46:57 +000012500/* MS Windows */
12501#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012502 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012503 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012504#endif
12505#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012506 /* Optimize for short life (keep in memory). */
12507 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012508 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012509#endif
12510#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012511 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012512 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012513#endif
12514#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012515 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012516 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012517#endif
12518#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012519 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012520 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012521#endif
12522
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012523/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012524#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012525 /* Send a SIGIO signal whenever input or output
12526 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012527 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012528#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012529#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012530 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012531 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012532#endif
12533#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012534 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012535 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012536#endif
12537#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012538 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012539 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012540#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012541#ifdef O_NOLINKS
12542 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012544#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012545#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012547 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012548#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012549
Victor Stinner8c62be82010-05-06 00:08:46 +000012550 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012551#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012552 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012553#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012554#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012556#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012557#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012559#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012560#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012561 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012562#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012563#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012564 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012565#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012566#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012568#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012569#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012571#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012572#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012573 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012574#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012575#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012576 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012577#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012598#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012599#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012601#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012602
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012603 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012604#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012606#endif /* ST_RDONLY */
12607#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012609#endif /* ST_NOSUID */
12610
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012611 /* GNU extensions */
12612#ifdef ST_NODEV
12613 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12614#endif /* ST_NODEV */
12615#ifdef ST_NOEXEC
12616 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12617#endif /* ST_NOEXEC */
12618#ifdef ST_SYNCHRONOUS
12619 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12620#endif /* ST_SYNCHRONOUS */
12621#ifdef ST_MANDLOCK
12622 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12623#endif /* ST_MANDLOCK */
12624#ifdef ST_WRITE
12625 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12626#endif /* ST_WRITE */
12627#ifdef ST_APPEND
12628 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12629#endif /* ST_APPEND */
12630#ifdef ST_NOATIME
12631 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12632#endif /* ST_NOATIME */
12633#ifdef ST_NODIRATIME
12634 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12635#endif /* ST_NODIRATIME */
12636#ifdef ST_RELATIME
12637 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12638#endif /* ST_RELATIME */
12639
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012640 /* FreeBSD sendfile() constants */
12641#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012643#endif
12644#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012645 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012646#endif
12647#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012648 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012649#endif
12650
Ross Lagerwall7807c352011-03-17 20:20:30 +020012651 /* constants for posix_fadvise */
12652#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012654#endif
12655#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012657#endif
12658#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012660#endif
12661#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012663#endif
12664#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012666#endif
12667#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012669#endif
12670
12671 /* constants for waitid */
12672#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012673 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12674 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12675 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012676#endif
12677#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012679#endif
12680#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012682#endif
12683#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012685#endif
12686#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012687 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012688#endif
12689#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012691#endif
12692#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012694#endif
12695#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012697#endif
12698
12699 /* constants for lockf */
12700#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012702#endif
12703#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012705#endif
12706#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012708#endif
12709#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012710 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012711#endif
12712
Guido van Rossum246bc171999-02-01 23:54:31 +000012713#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12715 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12716 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12717 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12718 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012719#endif
12720
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012721#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012722#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012724#endif
12725#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012727#endif
12728#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012730#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012731#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012733#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012734#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012736#endif
12737#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012739#endif
12740#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012742#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012743#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012745#endif
12746#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012748#endif
12749#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012751#endif
12752#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012754#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012755#endif
12756
Benjamin Peterson9428d532011-09-14 11:45:52 -040012757#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12759 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12760 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012761#endif
12762
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012763#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012764 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012765#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012766#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012768#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012769#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012771#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012772#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012774#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012775#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012777#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012778#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012780#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012781#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012783#endif
12784
Victor Stinner9b1f4742016-09-06 16:18:52 -070012785#ifdef HAVE_GETRANDOM_SYSCALL
12786 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12787 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12788#endif
12789
Victor Stinner8c62be82010-05-06 00:08:46 +000012790 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012791}
12792
12793
Martin v. Löwis1a214512008-06-11 05:26:20 +000012794static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012795 PyModuleDef_HEAD_INIT,
12796 MODNAME,
12797 posix__doc__,
12798 -1,
12799 posix_methods,
12800 NULL,
12801 NULL,
12802 NULL,
12803 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012804};
12805
12806
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012807static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012808
12809#ifdef HAVE_FACCESSAT
12810 "HAVE_FACCESSAT",
12811#endif
12812
12813#ifdef HAVE_FCHDIR
12814 "HAVE_FCHDIR",
12815#endif
12816
12817#ifdef HAVE_FCHMOD
12818 "HAVE_FCHMOD",
12819#endif
12820
12821#ifdef HAVE_FCHMODAT
12822 "HAVE_FCHMODAT",
12823#endif
12824
12825#ifdef HAVE_FCHOWN
12826 "HAVE_FCHOWN",
12827#endif
12828
Larry Hastings00964ed2013-08-12 13:49:30 -040012829#ifdef HAVE_FCHOWNAT
12830 "HAVE_FCHOWNAT",
12831#endif
12832
Larry Hastings9cf065c2012-06-22 16:30:09 -070012833#ifdef HAVE_FEXECVE
12834 "HAVE_FEXECVE",
12835#endif
12836
12837#ifdef HAVE_FDOPENDIR
12838 "HAVE_FDOPENDIR",
12839#endif
12840
Georg Brandl306336b2012-06-24 12:55:33 +020012841#ifdef HAVE_FPATHCONF
12842 "HAVE_FPATHCONF",
12843#endif
12844
Larry Hastings9cf065c2012-06-22 16:30:09 -070012845#ifdef HAVE_FSTATAT
12846 "HAVE_FSTATAT",
12847#endif
12848
12849#ifdef HAVE_FSTATVFS
12850 "HAVE_FSTATVFS",
12851#endif
12852
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012853#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012854 "HAVE_FTRUNCATE",
12855#endif
12856
Larry Hastings9cf065c2012-06-22 16:30:09 -070012857#ifdef HAVE_FUTIMENS
12858 "HAVE_FUTIMENS",
12859#endif
12860
12861#ifdef HAVE_FUTIMES
12862 "HAVE_FUTIMES",
12863#endif
12864
12865#ifdef HAVE_FUTIMESAT
12866 "HAVE_FUTIMESAT",
12867#endif
12868
12869#ifdef HAVE_LINKAT
12870 "HAVE_LINKAT",
12871#endif
12872
12873#ifdef HAVE_LCHFLAGS
12874 "HAVE_LCHFLAGS",
12875#endif
12876
12877#ifdef HAVE_LCHMOD
12878 "HAVE_LCHMOD",
12879#endif
12880
12881#ifdef HAVE_LCHOWN
12882 "HAVE_LCHOWN",
12883#endif
12884
12885#ifdef HAVE_LSTAT
12886 "HAVE_LSTAT",
12887#endif
12888
12889#ifdef HAVE_LUTIMES
12890 "HAVE_LUTIMES",
12891#endif
12892
12893#ifdef HAVE_MKDIRAT
12894 "HAVE_MKDIRAT",
12895#endif
12896
12897#ifdef HAVE_MKFIFOAT
12898 "HAVE_MKFIFOAT",
12899#endif
12900
12901#ifdef HAVE_MKNODAT
12902 "HAVE_MKNODAT",
12903#endif
12904
12905#ifdef HAVE_OPENAT
12906 "HAVE_OPENAT",
12907#endif
12908
12909#ifdef HAVE_READLINKAT
12910 "HAVE_READLINKAT",
12911#endif
12912
12913#ifdef HAVE_RENAMEAT
12914 "HAVE_RENAMEAT",
12915#endif
12916
12917#ifdef HAVE_SYMLINKAT
12918 "HAVE_SYMLINKAT",
12919#endif
12920
12921#ifdef HAVE_UNLINKAT
12922 "HAVE_UNLINKAT",
12923#endif
12924
12925#ifdef HAVE_UTIMENSAT
12926 "HAVE_UTIMENSAT",
12927#endif
12928
12929#ifdef MS_WINDOWS
12930 "MS_WINDOWS",
12931#endif
12932
12933 NULL
12934};
12935
12936
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012937PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012938INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012939{
Victor Stinner8c62be82010-05-06 00:08:46 +000012940 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012941 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012942 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012943
Brian Curtin52173d42010-12-02 18:29:18 +000012944#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012945 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012946#endif
12947
Victor Stinner8c62be82010-05-06 00:08:46 +000012948 m = PyModule_Create(&posixmodule);
12949 if (m == NULL)
12950 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012951
Victor Stinner8c62be82010-05-06 00:08:46 +000012952 /* Initialize environ dictionary */
12953 v = convertenviron();
12954 Py_XINCREF(v);
12955 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12956 return NULL;
12957 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012958
Victor Stinner8c62be82010-05-06 00:08:46 +000012959 if (all_ins(m))
12960 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012961
Victor Stinner8c62be82010-05-06 00:08:46 +000012962 if (setup_confname_tables(m))
12963 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012964
Victor Stinner8c62be82010-05-06 00:08:46 +000012965 Py_INCREF(PyExc_OSError);
12966 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012967
Guido van Rossumb3d39562000-01-31 18:41:26 +000012968#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 if (posix_putenv_garbage == NULL)
12970 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012971#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012972
Victor Stinner8c62be82010-05-06 00:08:46 +000012973 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012974#if defined(HAVE_WAITID) && !defined(__APPLE__)
12975 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012976 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12977 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012978#endif
12979
Christian Heimes25827622013-10-12 01:27:08 +020012980 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012981 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12982 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12983 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012984 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12985 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 structseq_new = StatResultType.tp_new;
12987 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012988
Christian Heimes25827622013-10-12 01:27:08 +020012989 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012990 if (PyStructSequence_InitType2(&StatVFSResultType,
12991 &statvfs_result_desc) < 0)
12992 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012993#ifdef NEED_TICKS_PER_SECOND
12994# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012995 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012996# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012998# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012999 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013000# endif
13001#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013002
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013003#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013004 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013005 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13006 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013007 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013008#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013009
13010 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013011 if (PyStructSequence_InitType2(&TerminalSizeType,
13012 &TerminalSize_desc) < 0)
13013 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013014
13015 /* initialize scandir types */
13016 if (PyType_Ready(&ScandirIteratorType) < 0)
13017 return NULL;
13018 if (PyType_Ready(&DirEntryType) < 0)
13019 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013020 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013021#if defined(HAVE_WAITID) && !defined(__APPLE__)
13022 Py_INCREF((PyObject*) &WaitidResultType);
13023 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13024#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013025 Py_INCREF((PyObject*) &StatResultType);
13026 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13027 Py_INCREF((PyObject*) &StatVFSResultType);
13028 PyModule_AddObject(m, "statvfs_result",
13029 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013030
13031#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013032 Py_INCREF(&SchedParamType);
13033 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013034#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013035
Larry Hastings605a62d2012-06-24 04:33:36 -070013036 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013037 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13038 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013039 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13040
13041 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013042 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13043 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013044 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13045
Thomas Wouters477c8d52006-05-27 19:21:47 +000013046#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013047 /*
13048 * Step 2 of weak-linking support on Mac OS X.
13049 *
13050 * The code below removes functions that are not available on the
13051 * currently active platform.
13052 *
13053 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013054 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013055 * OSX 10.4.
13056 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013057#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013058 if (fstatvfs == NULL) {
13059 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13060 return NULL;
13061 }
13062 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013063#endif /* HAVE_FSTATVFS */
13064
13065#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013066 if (statvfs == NULL) {
13067 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13068 return NULL;
13069 }
13070 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013071#endif /* HAVE_STATVFS */
13072
13073# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013074 if (lchown == NULL) {
13075 if (PyObject_DelAttrString(m, "lchown") == -1) {
13076 return NULL;
13077 }
13078 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013079#endif /* HAVE_LCHOWN */
13080
13081
13082#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013083
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013084 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013085 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13086
Larry Hastings6fe20b32012-04-19 15:07:49 -070013087 billion = PyLong_FromLong(1000000000);
13088 if (!billion)
13089 return NULL;
13090
Larry Hastings9cf065c2012-06-22 16:30:09 -070013091 /* suppress "function not used" warnings */
13092 {
13093 int ignored;
13094 fd_specified("", -1);
13095 follow_symlinks_specified("", 1);
13096 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13097 dir_fd_converter(Py_None, &ignored);
13098 dir_fd_unavailable(Py_None, &ignored);
13099 }
13100
13101 /*
13102 * provide list of locally available functions
13103 * so os.py can populate support_* lists
13104 */
13105 list = PyList_New(0);
13106 if (!list)
13107 return NULL;
13108 for (trace = have_functions; *trace; trace++) {
13109 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13110 if (!unicode)
13111 return NULL;
13112 if (PyList_Append(list, unicode))
13113 return NULL;
13114 Py_DECREF(unicode);
13115 }
13116 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013117
13118 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013119 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013120
13121 initialized = 1;
13122
Victor Stinner8c62be82010-05-06 00:08:46 +000013123 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013124}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013125
13126#ifdef __cplusplus
13127}
13128#endif